Reputation: 1527
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
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