b1 = Time.now
puts (1..100000).inject(0) { |x, y| x + y }
a1 = Time.now
puts "Time for inject: #{a1 - b1}"
b2 = Time.now
sum = 0
(1..100000).each do |value|
sum += value
end
puts sum
a2 = Time.now
puts "Time for each: #{a2 - b2}"
上面的 Ruby 代码比较了两种求和整数的方法。令我惊讶的是,更优雅的 inject 或 reduce 方法优于其他方法。为什么会这样?为什么人们会费心使用低效的inject 或reduce?仅仅因为它优雅?
PS:感谢所有鼓舞人心的答案。我的目的是询问导致差异的幕后情况。
最佳答案
在这种情况下我会用一点数学:
require "benchmark"
N = 5_000_000
Benchmark.bmbm do |bm|
bm.report "inject 1" do
(1..N).inject(0) { |x, y| x + y }
end
bm.report "inject 2" do
(1..N).inject(:+)
end
bm.report "each" do
sum = 0
(1..N).each do |value|
sum += value
end
end
bm.report "sum of finite arithmetic progression" do
((1 + N) * N) / 2
end
end
结果是:
% ruby sum.rb
Rehearsal ------------------------------------------------------------------------
inject 1 0.500000 0.000000 0.500000 ( 0.507497)
inject 2 0.320000 0.000000 0.320000 ( 0.322675)
each 0.370000 0.000000 0.370000 ( 0.380504)
sum of finite arithmetic progression 0.000000 0.000000 0.000000 ( 0.000005)
--------------------------------------------------------------- total: 1.190000sec
user system total real
inject 1 0.500000 0.000000 0.500000 ( 0.507697)
inject 2 0.320000 0.000000 0.320000 ( 0.322323)
each 0.370000 0.000000 0.370000 ( 0.380307)
sum of finite arithmetic progression 0.000000 0.000000 0.000000 ( 0.000004)
%
更好的数学总是更快:)
关于Ruby Map/Reduce 函数必须高效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7679941/