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.


--
-yossef