Indeed, a benchmark is the best way to find out. Here's a quick one, with
slight changes to your original code and no puts, and including Jeremy's
idiomatic suggestion.
The numbers I got on my machine are:
for loop 1.210000 0.000000 1.210000 ( 1.225631)
while loop 1.460000 0.010000 1.470000 ( 1.469653)
times loop 1.980000 0.000000 1.980000 ( 1.998238)
I expected the times version to be faster too, but it looks like the for
loop is the fastest in this case.
This is interesting, and in an effort to get slightly more accurate data
on this microbenchmark, I tweaked your code a bit to ensure that the
loops are performing the same work in each case. I then looped the test
5 times:
require 'benchmark'
count = 1_000_000
5.times do
Benchmark.benchmark do |bm|
bm.report("for loop") {
for i in 0..count-1
i += 1
i * i
end
}
bm.report("while loop") {
i = 0
while i < count
i += 1
i * i
end
}
bm.report("times loop") {
count.times do |i|
i += 1
i * i
end
}
end
puts
end
=>
for loop 1.656000 0.000000 1.656000 ( 1.888000)
while loop 1.750000 0.000000 1.750000 ( 1.860000)
times loop 1.735000 0.000000 1.735000 ( 1.954000)
for loop 1.984000 0.000000 1.984000 ( 1.980000)
while loop 1.625000 0.000000 1.625000 ( 1.848000)
times loop 1.813000 0.000000 1.813000 ( 1.967000)
for loop 1.797000 0.000000 1.797000 ( 1.923000)
while loop 1.687000 0.000000 1.687000 ( 1.850000)
times loop 1.938000 0.000000 1.938000 ( 1.956000)
for loop 1.687000 0.000000 1.687000 ( 1.902000)
while loop 1.813000 0.016000 1.829000 ( 1.842000)
times loop 1.718000 0.000000 1.718000 ( 1.943000)
for loop 1.782000 0.000000 1.782000 ( 1.901000)
while loop 1.734000 0.000000 1.734000 ( 1.843000)
times loop 1.734000 0.000000 1.734000 ( 1.956000)
As can be seen, there is a fair bit of variance in the benchmark. There
does not appear to be a clear winner overall.
-Jeremy