On 30.10.2010 00:47, Jeremy Bopp wrote: > On 10/29/2010 5:36 PM, Ammar Ali wrote: >> I see. I excluded the i += 1 from the for and times loops because that is >> done automatically. Adding them seemed to add work that was not necessary >> for those constructs, and IMHO, make the benchmark inaccurate. > > That's definitely a debatable point in this benchmark because we are > essentially doubling the number of add operations for the loops that > perform it implicitly. However, we also want to see how the choice of > looping mechanism affects the operations performed within the loop, so > making the looped operations completely identical has its merits. I'm sorry but this is nonsense: different loop constructs are benchmarked precisely to determine which iteration is quicker. Incrementing the loop variable is one of the things that make up the difference between looping constructs so there is no point in doing this "manually" just to make loop bodies look identical. Here's my version Robert@babelfish ~ $ ruby19 x.rb Rehearsal ---------------------------------------------- for loop 2.168000 0.000000 2.168000 ( 2.211000) while loop 1.981000 0.000000 1.981000 ( 2.015000) times loop 2.075000 0.016000 2.091000 ( 2.150000) ------------------------------------- total: 6.240000sec user system total real for loop 2.106000 0.000000 2.106000 ( 2.149000) while loop 1.919000 0.000000 1.919000 ( 1.919000) times loop 2.012000 0.000000 2.012000 ( 2.063000) Robert@babelfish ~ $ cat x.rb require 'benchmark' count = 1_000_000 Benchmark.bmbm do |bm| bm.report("for loop") { 5.times do for i in 0...count i * i end end } bm.report("while loop") { 5.times do i = 0 while i < count i * i i += 1 end end } bm.report("times loop") { 5.times do count.times do |i| i * i end end } end puts > Regardless, the big thing we see is that the loops all perform roughly > equivalently overall. Their relative differences in overhead will > likely be dwarfed by the looped operations in the real world. Agreed. > In this case, I would choose the more idiomatic approach for the sake of > brevity, familiarity, and safety. I really hate how easy it is to have > off-by-one errors and similar problems in the more manually iterated for > and while constructs. Actually there was one in the first posting of this thread: > for i in 1..layers[0].count-1 > puts i > end > > Is it equivalent in efficiency to this? > > int i = 1 > while i < layers[0].count-1 > puts i > i+=1 > end The answer is no because the second one does one less iteration. :-) Please note also that you can use three dot ranges to exclude the end so the first one could be rewritten as for i in 1...layers[0].count # ... end Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/