views:

103

answers:

2

Which of the following pieces of code is more expensive?

x = my_array.inject {|sum,i| int+=i }

or

x = eval(my_array.join('+'))
+12  A: 

Try them:

#!/usr/local/bin/ruby -w
require 'benchmark'
iterations = 1000000

Benchmark.bmbm do |bench|
  numbers = (1..100).to_a

  bench.report('inject') do
    x = numbers.inject { |sum, num| sum + num }
  end
  bench.report('eval') do
    x = eval(numbers.join('+'))
  end
end

Which gives:

telemachus ~ $ ruby bench.rb 
Rehearsal ------------------------------------------
inject   0.000000   0.000000   0.000000 (  0.000029)
eval     0.000000   0.000000   0.000000 (  0.000261)
--------------------------------- total: 0.000000sec

             user     system      total        real
inject   0.000000   0.000000   0.000000 (  0.000047)
eval     0.000000   0.000000   0.000000 (  0.000186)

But actually, I think you're micro-optimizing. I would use inject unless it was grossly inefficient, since it's what the method was built for.

Also I think that your code for inject has two issues. First, you don't mean int, you mean sum. Second, you can simply add the items, rather than use +=. The first paramter to inject automatically accumulates value.

Telemachus
eval is gonna be far slower due to the nauture of it, avoid it when you can.
khelll
A: 

As a rule of a thumb, eval code is always slower than its reasonable eval-free alternative (as in this case). It's also potentially insecure if it processes user input.

And just for the record, in Rails (or after require 'activeresource') you can also use numbers.sum method, which is roughly as fast as inject and IMHO more readable.

Lukas Stejskal