2008-11-25 78 views
1

我经常听到过Ruby的注射方法批评为“慢”。由于我比较喜欢的功能,并看到其他语言的等价物,我很好奇,如果它只是Ruby的是很慢,或者如果它本身是做事情慢的方式(应避免非例如方法实施小集合)?#inject和缓慢

回答

3

inject就像fold,并且可以在其他语言非常有效的,特别是fold_left,因为它是尾递归。

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 

所以是的,它是缓慢的,但随着科技进步出现在实施过程中,它应该成为一个非问题。没有什么固有的关于它在做什么,需要它要慢一些。

0

each_with_object可能比inject更快,如果你是变异现有的对象,而不是建立在每个块的新对象。