Be careful with ranges (Ruby)

I recently installed the wonderful test_benchmark plugin for Rails, and ran it against our code. I was surprised to find that we had a couple unit tests that were taking 4 seconds to complete.

Digging in, I found code that was doing the following on a time range:


range = # .. a time range 24 hours "wide"
start_time = range.min
end_time = range.max

I looked up the API for Range, and there are no .min and .max methods defined, but they live in enumerable. So what’s going on here?

A little more digging:


>> count = 0; r.max { |a,b| count +=1; a <=> b }
=> Fri Apr 03 20:07:29 UTC 2009
>> count
=> 88200

Oops. 88,200 comparisons for a time range. Switching the code in the test and the class under test to use .first() and .last() instead of .min() and .max(), and I shaved off a cool 8 seconds from rake test

Leave a Reply