3

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
4

2 に答える 2

3

ご指摘いただきありがとうございます。

そうです、トピックは次のように表現されているはずです: 「eval によって作成された動的メソッドのパフォーマンスと、define_method によって作成されたメソッドとの比較」。

このバグは、本日中にコンテンツで修正される予定です。

メソッド定義のパフォーマンス デルタは重要な考慮事項ですが、特に AST がキャッシュされるため、(少なくとも ruby​​ では) 実際に重要であるとは考えていません。

テジャス

チーム RubyMonk

于 2013-02-25T18:42:34.697 に答える
3

あなたが RubyMonk から示したベンチマークは、 orを使用したメソッドの定義の速さを測定していません。結果のメソッドを呼び出す速度を測定しています。そのため、そのように読みます。evaldefine_method

Ruby インタープリターの実装について理解を深めるまで明らかではない理由により、evalまたはを介し​​て定義されたメソッドの速度define_methodは一般的に同じではありません。

于 2013-02-25T16:33:15.940 に答える