On 02/05/2010 07:36 PM, Aaron Gifford wrote: > What's the fastest way to iterate over a range in variable increments? > > For example, using irb (1.9.1): > > irb(main):001:0> > a=0;s=Time.now;i=0;while(i<1000000000);a+=i;i+=5;end;e=Time.now;p > e-s;p a > 8.715433734 > 99999999500000000 > => 99999999500000000 > irb(main):002:0> > a=0;s=Time.now;Range.new(0,1000000000,true).step(5){|i|a+=i};e=Time.now;p > e-s;p a > 18.932204045 > 99999999500000000 > => 99999999500000000 > > As you can see I'm stepping by 5 over the range 0 to 1000000000 > exclusive (excluding the last item) doing a simple operation each > iteration (the operation above is totally contrived). > > In this case, it appears that while outperforms Range's step method. robert@fussel:~$ ruby19 xx.rb Rehearsal -------------------------------------------------- while 15.650000 0.030000 15.680000 ( 17.892211) range step 33.650000 0.070000 33.720000 ( 38.560748) step 30.680000 0.110000 30.790000 ( 34.767791) ---------------------------------------- total: 80.190000sec user system total real while 15.700000 0.050000 15.750000 ( 18.651631) range step 33.690000 0.060000 33.750000 ( 38.554879) step 30.660000 0.100000 30.760000 ( 35.095686) robert@fussel:~$ cat xx.rb require 'benchmark' LI = 1000000000 ST = 5 Benchmark.bmbm 15 do |b| b.report "while" do i = 0 while i < LI i += ST end end b.report "range step" do |b| (0...LI).step ST do end end b.report "step" do |b| 0.step LI, ST do end end end robert@fussel:~$ I think we are seeing an effect of the missing call to the block that happens on each iteration for #step approaches. The while loop does not have this overhead. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/