2011-09-02 4 views
8

速く、後で呼び出しにどのようなものです:Rubyではより速く実行される:エイリアスメソッドの定義またはalias_methodの使用?

def first_method?() second_method?() end 

または

alias_method :first method, :second_method 

し、可能な場合はなぜですか?

(注:私はよりよい/より良いなどが何であるかを尋ねていない - >のみ生速度を、それが高速である理由はここに興味深いものです)

+1

最初のバージョンに追加のメソッド検索が1つあることは明らかですか? Rubiniusはいくつかのコードを単純化して、同じものにすることができます。 –

答えて

7

ソースコードを簡単に見ては、あなたのトリックが表示されます:

http://www.ruby-doc.org/core/classes/Module.src/M000447.html

alias_methodが別のメソッドを呼び出すRubyでメソッドを定義し、さらにCで書かれ、2の方法になりますルックアップと呼び出し。

だから、alias_methodは高速にする必要があります。

+0

+1実装を見てください。) – lucapette

+1

はい、 )の 'alias_method'は本当に問題ではありません(質問を誤解していない限り)。ポイントは、明らかに 'alias_method'は元の関数オブジェクトを参照するシンボルテーブルに別のエントリを作成するだけです。そして、これはリンクされたソースから見ることはできません。 –

+0

これは重要なポイントではありません。シンボルテーブルにエントリを作成するだけでなく、エイリアス化されたメソッドの結果を返す必要があります。これは、明示的に別のメソッドを呼び出すメソッドを(ルビを使用して)定義することとはまったく異なります。 –

13

少なくともRubyの1.8.6で、エイリアシングが速くなるようです:中

#!/usr/local/bin/ruby 

require 'benchmark' 

$global_bool = true 

class Object 
    def first_method? 
    $global_bool 
    end 

    def second_method? 
    first_method? 
    end 

    alias_method :third_method?, :first_method? 
end 

Benchmark.bm(7) do |x| 
    x.report("first:") { 1000000.times { first_method? }} 
    x.report("second:") { 1000000.times { second_method? }} 
    x.report("third:") { 1000000.times { third_method? }} 
end 

結果:

$ ./test.rb 
      user  system  total  real 
first: 0.281000 0.000000 0.281000 ( 0.282000) 
second: 0.469000 0.000000 0.469000 ( 0.468000) 
third: 0.281000 0.000000 0.281000 ( 0.282000) 

はもちろん、あなたが1つの少ないのメソッド呼び出し(ルックアップレシーバを...)持っています。だから、それがより速いのは当然のようです。

+1

私は同様のベンチマークを行っており、あなたが言っていることを確認しているようです。エイリアスが少し速くなると言うだけで十分です... – lucapette

+1

'alias'のパフォーマンスを' alias_method'に似ています。 – lulalala

関連する問題