RubyMonk (ペイウォールの背後にあるリンクのため、提供されていません) で演習を行っている間、次のコードとeval
比較してメソッドを定義するパフォーマンスを測定するために提供されています。define_method
require 'benchmark'
class Monk
eval "def zen; end"
define_method(:zen_block) {}
end
monk = Monk.new
Benchmark.bmbm do |x|
x.report("eval zen: ") { 1_000_000.times { monk.zen } }
x.report("define_method zen: ") { 1_000_000.times { monk.zen_block } }
end
Ruby の初心者として、私の質問は次のとおりです。メソッドがzen
実際zen_block
にインタープリターによって「コンパイル」されるのはいつですか (正しい言葉かどうかはわかりません)。zen
との両方zen_block
が呼び出しごとに再定義される可能性は低いようです。私がこれまでに理解したことから、パフォーマンスを測定する正しい方法は次のようになります。
require 'benchmark'
class Monk
def with_eval
eval "def zen; end"
end
def with_define_method
self.class.send(:define_method,:zen_block) {}
end
end
Benchmark.bmbm do |x|
x.report("eval zen: ") { 1_000_000.times { monk.with_eval } }
x.report("define_method zen: ") { 1_000_000.times { monk.with_define_method } }
end
最初のブロックは、私のマシンでこれらの結果を生成します (時間をもう少し堅牢にするために、反復回数を 100 万回に増やしました)。
Rehearsal -------------------------------------------------------
eval zen: 0.070000 0.000000 0.070000 ( 0.074196)
define_method zen: 0.120000 0.000000 0.120000 ( 0.118621)
---------------------------------------------- total: 0.190000sec
2 番目のブロックの結果 (私の提案):
Rehearsal -------------------------------------------------------
eval zen: 7.740000 0.000000 7.740000 ( 7.743741)
define_method zen: 1.620000 0.000000 1.620000 ( 1.617666)
---------------------------------------------- total: 9.360000sec