I’ve got this block of code:
date_counter = Time.mktime(2011,01,01,00,00,00,"+05:00")
@weeks = Array.new
(date_counter..Time.now).step(1.week) do |week|
logger.debug "WEEK: " + week.inspect
@weeks << week
end
Technically, the code works, outputting:
Sat Jan 01 00:00:00 -0500 2011
Sat Jan 08 00:00:00 -0500 2011
Sat Jan 15 00:00:00 -0500 2011
etc.
But the execution time is complete rubbish! It takes approximately four seconds to compute each week.
Is there some grotesque inefficiency that I’m missing in this code? It seems straight-forward enough.
I’m running Ruby 1.8.7 with Rails 3.0.3.
Assuming MRI and Rubinius use similar methods to generate the range the basic algorithm used with all the extraneous checks and a few Fixnum optimisations etc. removed is:
(See the Rubinius source code)
For a
Timeobject#succreturns the time one second later. So even though you are asking it for just each week it has to step through every second between the two times anyway.Edit: Solution
Build a range of Fixnum’s since they have an optimised
Range#stepimplementation.Something like: