Huliax
Huliax

Reputation: 1527

Is alias_method faster than def foo; bar; end?

Sorry for the title. I don't quite know how to state the question in a concise way.

Basically, I've run across some code that does a lot of the following:

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

I know it doesn't matter much but I'm just curious. Will the interpreter optimize this or should I go ahead and just get rid of the definitions of bar and baz and just use alias_method? I don't see the point of having one more entry in the call stack.

Upvotes: 0

Views: 67

Answers (1)

Jordan Running
Jordan Running

Reputation: 106027

Intuitively I would guess alias_method is faster, because method dispatch in Ruby is (relatively) costly and as far as I know the Ruby interpreter isn't smart enough to replace a method definition with an alias.

However, Paul is right, we should just benchmark it. Thankfully that's extremely easy in Ruby. Next time you can do it yourself. Here's our benchmark (we use the benchmark-ips gem because it automatically runs our benchmark many times):

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

The results:

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

So there's your answer. Aliases defined with alias and alias_method perform identically to calling the original method directly, but calling the method through an intermediary is about 20% slower.

Upvotes: 4

Related Questions