Ruby has a built-in loop
command that executes the block following it forever (or until stopped by break
). However, when comparing it against the functionally similar while true
, it is significantly slower:
require "benchmark/ips"
NUMBER = 100_000_000
def fast
index = 0
while true
break if index > NUMBER
index += 1
end
end
def slow
index = 0
loop do
break if index > NUMBER
index += 1
end
end
Benchmark.ips do |x|
x.report("While Loop") { fast }
x.report("Kernel loop") { slow }
x.compare!
end
Under Ruby 2.4.1 (p111 (2017-03-22 revision 58053) [x64-mingw32]), the difference is striking:
Warming up --------------------------------------
While Loop 1.000 i/100ms
Kernel loop 1.000 i/100ms
Calculating -------------------------------------
While Loop 0.630 (± 0.0%) i/s - 4.000 in 6.350897s
Kernel loop 0.190 (± 0.0%) i/s - 1.000 in 5.274249s
Comparison:
While Loop: 0.6 i/s
Kernel loop: 0.2 i/s - 3.32x slower
Why is there such a performance difference? And why is the single-purpose loop
command worse at its job than the general-purpose while
?
(Benchmark copied from here, licensed under CC-BY-SA)