I tweeted about this, but figured it deserve a more lasting treatment.
If you've ever used
Range#max you may have inadvertently slowed
your code significantly.
Both of those ought to be O(1) - constant time. After all, a Range in Ruby consist of two values, and though you can't be assured whether or not the first one or the last one is the smallest/biggest one, the obvious implementation is this:
def min first last ? first : last end
.. and the equivalent one for
Range#max. Except that's not what happens,
as you can easily convince yourself by doing:
$ irb irb(main):001:0> (1..10000000).max => 10000000 irb(main):002:0>
... and see how slow it is. Eww. The explanation is that min/max are only provided in generic versions that iterate over the full Range (so that the same implementation also works on other collections).
If your app, like mine, frequently needs the smallest or greatest value in a Range, it may be time to monkey patch:
class Range def min first last ? first : last end def max first >= last ? first : last end end
For the app that made me notice this problem, adding the above monkey patch
caused a 30% speedup. Of course, if most of your ranges are small, or you
Range#max anywhere, you may not notice any difference