|
Ruby: benchmarking ways to pass options to a method
I've wondered before what the fastest way is to pass a hash of options to a method in Ruby.. so today I benchmarked a few methods I've used in the past.
I've seen three main ways of passing an options hash to a method and extracting the options or use default values if they weren't passed in:
- Merge the options with a hash of defaults, then assign values to local variables (or just use the options hash directly within the method)
- Use something like var = options[:var] || 'default'
- Use the delete method on the hash, e.g., var = options.delete(:var) || 'default'
From what I can tell, using delete is the fastest:
require 'benchmark'
def ops_delete(ops={})
a = ops.delete(:a) || 11
b = ops.delete(:b) || 22
c = ops.delete(:c) || 33
d = ops.delete(:d) || 44
end
def ops_merge(ops={})
ops = {:a => 11, :b => 22, :c => 33, :d => 44}.merge(ops)
a = ops[:a]
b = ops[:b]
c = ops[:c]
d = ops[:d]
end
def ops_or(ops={})
a = ops[:a] || 11
b = ops[:b] || 22
c = ops[:c] || 33
d = ops[:d] || 44
end
n = 100000
puts "With no option values passed"
Benchmark.bmbm(7) do |x|
x.report("delete:") { n.times do ops_delete; end }
x.report("merge:") { n.times do ops_merge; end }
x.report("or_nil:") { n.times do ops_or; end }
end
puts
puts "With some option values passed"
Benchmark.bmbm(7) do |x|
x.report("delete:") { n.times do ops_delete(:a => 5, :c => 2); end }
x.report("merge:") { n.times do ops_merge(:a => 5, :c => 2); end }
x.report("or_nil:") { n.times do ops_or(:a => 5, :c => 2); end }
end
puts
puts "With all option values passed"
Benchmark.bmbm(7) do |x|
x.report("delete:") { n.times do ops_delete(:a => 5, :b => 1, :c => 2, :d => 4); end }
x.report("merge:") { n.times do ops_merge(:a => 5, :b => 1, :c => 2, :d => 4); end }
x.report("or_nil:") { n.times do ops_or(:a => 5, :b => 1, :c => 2, :d => 4); end }
end
Results (rehearsals omitted):
With no option values passed
user system total real
delete: 0.210000 0.000000 0.210000 ( 0.209877)
merge: 0.720000 0.000000 0.720000 ( 0.750394)
or_nil: 0.260000 0.000000 0.260000 ( 0.258416)
With some option values passed
user system total real
delete: 0.250000 0.000000 0.250000 ( 0.255536)
merge: 0.830000 0.000000 0.830000 ( 0.831358)
or_nil: 0.310000 0.000000 0.310000 ( 0.314737)
With all option values passed
user system total real
delete: 0.310000 0.000000 0.310000 ( 0.306889)
merge: 0.900000 0.000000 0.900000 ( 0.905261)
or_nil: 0.340000 0.000000 0.340000 ( 0.348061)
This was done in Ruby 1.8.4 on a 2GHz MacBook Intel Core Duo with 1GB 667 MHz DDR2 SDRAM.
(2008-02-02 14:34:51.0/2008-02-02 14:34:51.0)
Permalink
Trackback: http://blogs.sun.com/bdonovan/entry/ruby_benchmarking_ways_to_pass
|