[当您只有锤子时,一切看起来都像钉子。因此,在发现Array#each
和Array#map
以及其他可迭代方法的实用性,优雅性和语法乐趣之前,可以说是Ruby中的Array#select
方法。我很好奇的是:
为什么使用更精确的可迭代方法会真正提高性能?这是真的吗?
例如,在
require 'benchmark'
array = (1..100000).to_a
puts Benchmark.measure {
100.times do
array.map { |el| el.even? }
end
}
puts Benchmark.measure {
new_array = []
100.times do
array.each do |el|
new_array << el.even?
end
end
}
# ruby bench.rb
# 0.460292 0.017666 0.477958 ( 0.479364)
# 0.521223 0.021833 0.543056 ( 0.544532)
Benchmark
显示出12%的时间性能差异,有利于Array#map
。在以下代码中:
puts Benchmark.measure {
100.times do
array.select { |el| el.even? }
end
}
puts Benchmark.measure {
new_array = []
100.times do
array.each do |el|
if el.even?
new_array << el
end
end
end
}
# ruby bench.rb
# 0.423335 0.009808 0.433143 ( 0.434633)
# 0.486055 0.011327 0.497382 ( 0.499155)
[Array#select
每次都击败杰里操纵的Array#each
。
那么为什么这些更精确的方法产生明显更好的性能?这是Ruby和/或所有语言的通用公理吗?
在两个示例的第二种情况下,每次迭代期间都有一个赋值。第一个没有分配任何内容。