2007/10/12, Yossef Mendelssohn <ymendel / pobox.com>: > On Oct 11, 9:55 pm, Brian Adkins <lojicdot... / gmail.com> wrote: > > On Oct 11, 9:30 pm, Marek Kasperkiewicz <m.kasperkiew... / gmail.com> > > wrote: > > > > > If i try this > > > puts (1..10).max > > > it runs fine. > > > If i try this > > > puts (1..100000000).max > > > It is extremely slow. Instead of using straight math max= 100000000-1 > > > it uses some king of interator to find out the value of max. > > > What is the catch here? > > > > Well, one advantage of (1..N).max compared to your 'straight math' > > method is the former provides the correct answer and the latter does > > not. :) > > > > However, for efficiency, if for some reason you don't want to simply > > use max = N, you'll find max = (1..N).end is much faster than max = > > (1..N).max since it doesn't look at each element in the range. > > > > The Enumerable#max method is generalized to also work for cases such > > as max = [1,10,100,10,1].max > > I was thinking Range#last, but that has the same problem as Range#end > (probably one is an alias for the other). > > (1..10).last (or end) => 10 > (1..10).max => 10 > > (1...10).last (or end) => 10 > (1...10).max => 9 > > What you want is something like > > class Range > def quick_max > last - (exclude_end? ? 1 : 0) > end > end > > Of course, if you're not using Fixnums, this is wrong. Maybe if > classes defined prec (instead of only succ), this could be easy. I believe not. #max *has* to use <=> for a proper result. Although it might be common that <=> and #succ represent the same ordering this is not required. Actually there is a pretty straightforward example: irb(main):001:0> ("a".."aa").last => "aa" irb(main):002:0> ("a".."aa").max => "z" irb(main):003:0> puts ("a".."aa").to_a a b c d e f g h i j k l m n o p q r s t u v w x y z aa => nil There is no optimization that works for all and I guess that's the reason why Matz did not bother to provide Range#max and Enumerable#max is used instead. And this has necessarily O(n). After all: if you are smart enough to use Ruby then you are probably also smart enough to not use #max on an integer range. :-) Kind regards robert