evalよりinsntance_variable_setのほうが10倍速かった話
コンストラクタで、インスタンス変数を初期化する際に引数があればそれを、なければデフォルト値を入れたかった。
class Hoge attr_accessor :foo, :bar, :baz DEFAULT = { :foo => 'foo', :bar => 'baz', :baz => 'baz', } def initialize(opt = {}) DEFAULT.each { |key, val| instance_variable_set("@#{key}", opt[key] || val) # ここと } end end class Fuga attr_accessor :foo, :bar, :baz DEFAULT = { :foo => 'foo', :bar => 'baz', :baz => 'baz', } def initialize(opt = {}) DEFAULT.each { |key, val| eval "@#{key} = opt[:#{key}] || val" # ここ } end end require "benchmark" Benchmark.bmbm { |x| x.report('instance_variable_set') { (1..1_000_000).each { Hoge.new(:foo => 'FOO') } } x.report('eval') { (1..1_000_000).each { Fuga.new(:foo => 'FOO') } } }
Rehearsal --------------------------------------------------------- instance_variable_set 5.570000 0.010000 5.580000 ( 5.590429) eval 50.110000 0.060000 50.170000 ( 50.348506) ----------------------------------------------- total: 55.750000sec user system total real instance_variable_set 6.010000 0.000000 6.010000 ( 6.011255) eval 51.020000 0.040000 51.060000 ( 51.103497)
10倍くらいinstance_variable_setの方が速かった。
というかご多分に漏れず、evalが遅いのか。