TL;DR
- 在 Ruby 1.8 中使用
for 循环提高性能
- 在现有项目中使用
for 循环到标准
- 使用
each 循环将副作用降至最低
- 首选
each循环。
each 最大限度地减少副作用
for 和 each 之间的主要区别在于范围。
each 函数需要一个块。块创建一个新的词法范围。这意味着在函数范围内声明的任何变量在函数之后将不再可用。
[1, 2, 3].each do |i|
a = i
end
puts a
# => NameErrror: undefined local variable or method `a' for main:Object
鉴于:
for i in [1, 2, 3]
a = i
end
puts a
# => 3
因此,使用each 语法可以最大限度地降低副作用的风险。
确定退出点?
也就是说,在某些特殊情况下,for 循环可能会有所帮助。具体来说,当找出循环退出的位置时。
for i in 1..3
a = i
break if i % 2 == 0
end
puts a
# => 0
虽然有更好的方法:
a = (1..3).each do |i|
break i if i % 2 == 0
end
每个都更快(在 Ruby 2.0 中)
Benchmark.bm(8) do |x|
x.report "For" do
max.times do
for i in 1..100
1 + 1
end
end
end
x.report "Each" do
max.times do
(1..100).each do |t|
1+1
end
end
end
end
Ruby 2.0
user system total real
For 6.420000 0.000000 6.420000 ( 6.419870)
Each 5.830000 0.000000 5.830000 ( 5.829911)
Ruby 1.8.6(较慢的机器)
user system total real
For 17.360000 0.000000 17.360000 ( 17.409992)
Each 21.130000 0.000000 21.130000 ( 21.250754)
基准 2
如果您阅读评论线索,则在 for 与 each 中讨论了创建对象的速度。 link provided 具有以下基准(尽管我已经清理了格式并修复了语法错误)。
b = 1..10e5
Benchmark.bmbm (10) do |x|
x.report "each {}" do
b.each { |r| r + 1 }
end
x.report "each do end" do
b.each do |r|
r + 1
end
end
x.report "for do end" do
for r in b do
r + 1
end
end
end
Ruby 2.0
user system total real
each {} 0.150000 0.000000 0.150000 ( 0.144643)
each do end 0.140000 0.000000 0.140000 ( 0.143244)
for do end 0.150000 0.000000 0.150000 ( 0.147112)
Ruby 1.8.6
user system total real
each {} 0.840000 0.000000 0.840000 ( 0.851634)
each do end 0.730000 0.000000 0.730000 ( 0.732737)
for do end 0.650000 0.000000 0.650000 ( 0.647186)