Ruby の inject メソッドが「遅い」と批判されるのをよく耳にします。私は関数が好きで、他の言語で同等のものを見ているので、遅いのはRubyのメソッドの実装だけなのか、それとも物事を行うのに本質的に遅い方法なのか (例えば、小さくないコレクションでは避けるべきです) に興味があります)?
3 に答える
3
injectに似ており、特に末尾再帰であるためfold、他の言語では非常に効率的です。fold_left
于 2008-11-25T21:13:08.017 に答える
2
これは主に実装の問題ですが、これにより比較の良いアイデアが得られます。
$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
$ ruby exp/each_v_inject.rb
Rehearsal -----------------------------------------------------
loop 0.000000 0.000000 0.000000 ( 0.000178)
fixnums each 0.790000 0.280000 1.070000 ( 1.078589)
fixnums each add 1.010000 0.290000 1.300000 ( 1.297733)
Enumerable#inject 1.900000 0.430000 2.330000 ( 2.330083)
-------------------------------------------- total: 4.700000sec
user system total real
loop 0.000000 0.000000 0.000000 ( 0.000178)
fixnums each 0.760000 0.300000 1.060000 ( 1.079252)
fixnums each add 1.030000 0.280000 1.310000 ( 1.305888)
Enumerable#inject 1.850000 0.490000 2.340000 ( 2.340341)
exp/each_v_inject.rb
require 'benchmark'
total = (ENV['TOTAL'] || 1_000).to_i
fixnums = Array.new(total) {|x| x}
Benchmark.bmbm do |x|
x.report("loop") do
total.times { }
end
x.report("fixnums each") do
total.times do |i|
fixnums.each {|x| x}
end
end
x.report("fixnums each add") do
total.times do |i|
v = 0
fixnums.each {|x| v += x}
end
end
x.report("Enumerable#inject") do
total.times do |i|
fixnums.inject(0) {|a,x| a + x }
end
end
end
はい、遅いですが、実装で改善が行われると、問題になることはありません。それが何をしているのかについて、それを遅くする必要があるという固有のものは何もありません。
于 2008-11-26T21:43:29.437 に答える
0
each_with_objectinject各ブロックで新しいオブジェクトを作成するのではなく、既存のオブジェクトを変更している場合は、よりも高速になる可能性があります。
于 2011-06-18T13:55:50.180 に答える