在 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
第二个区块的结果(我的建议):
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