Ruby内置了一个loop
命令,它执行紧随其后的代码块,一直循环执行(或直到被break
停止)。然而,与功能类似的while true
相比,它明显更慢:
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
在 Ruby 2.4.1 (p111 (2017-03-22 revision 58053) [x64-mingw32]) 中,差异非常明显:
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
为什么性能会有这样的差异?为什么单一目的的
loop
命令比通用的 while
在其工作方面更差呢?(基准测试参考自 这里,根据 CC-BY-SA 许可证授权)
begin i+=1 end while i<=NUMBER
仍然更快。想象一下... - dawgStopIteration
异常。它的响应是跳出循环。如果enum = [1,2,3].to_enum; loop do; enum.next; end
,当枚举器生成其最后一个值后执行next
时,将引发StopIteration
异常。理论上,相关开销可能会影响基准测试结果,但我预计使用while(true)
或while(1)
(FORTRAN 遗留物)节省的时间通常会被执行循环内语句所花费的时间所抵消。为了保持一致性,我总是使用loop
。 - Cary Swoveland