alias_method比def foo更快;酒吧;结束?

时间:2014-12-09 17:11:45

标签: ruby

对不起标题。我不太清楚如何以简洁的方式陈述问题。

基本上,我遇到了一些执行以下操作的代码:

def foo; ...; end
def bar; foo; end
def baz; foo; end

我知道这并不重要,但我只是好奇。解释器是否会对此进行优化,还是应该继续使用barbaz的定义并使用alias_method?我不明白在调用堆栈中还有一个条目。

1 个答案:

答案 0 :(得分:4)

直觉我猜alias_method更快,因为Ruby中的方法调度是(相对)昂贵的,据我所知,Ruby解释器不够聪明,不能用别名替换方法定义。

然而,保罗是对的,我们应该只是对它进行基准测试。值得庆幸的是,在Ruby中非常容易。下次你可以自己做。这是我们的基准测试(我们使用benchmark-ips gem,因为它会自动运行我们的基准测试多次):

require "benchmark/ips"

class Test
  def foo
    @a = 1 + 1 # do some trivial work
  end

  def call_foo
    foo
  end

  alias :foo_alias :foo
  alias_method :foo_alias_method, :foo
end

test = Test.new

Benchmark.ips do |x|
  x.report("foo") { test.foo }
  x.report("call_foo") { test.call_foo }
  x.report("foo_alias") { test.foo_alias }
  x.report("foo_alias_method") { test.foo_alias_method }

  x.compare!
end

结果:

Calculating -------------------------------------
                 foo    168627 i/100ms
            call_foo    164095 i/100ms
           foo_alias    170038 i/100ms
    foo_alias_method    167373 i/100ms
-------------------------------------------------
                 foo  8986656.9 (±1.8%) i/s -   45023409 in   5.011722s
            call_foo  7532860.7 (±3.2%) i/s -   37741850 in   5.016101s
           foo_alias  8960414.7 (±2.8%) i/s -   44890032 in   5.014278s
    foo_alias_method  8960833.8 (±2.7%) i/s -   44855964 in   5.010400s

Comparison:
                 foo:  8986656.9 i/s
    foo_alias_method:  8960833.8 i/s - 1.00x slower
           foo_alias:  8960414.7 i/s - 1.00x slower
            call_foo:  7532860.7 i/s - 1.19x slower

所以有你的答案。使用aliasalias_method定义的别名与直接调用原始方法的执行方式相同,但通过中介调用该方法的速度要慢20%。