2012-11-21 14 views
10

Iちょうどテストattr_accessor:Rubyのattr_accessorとgetter/setterのベンチマーク:なぜアクセッサは高速ですか?同等のゲッター/セッター・メソッドに対する

class A 
    # we define two R/W attributes with accessors 
    attr_accessor :acc, :bcc 

    # we define two attributes with getter/setter-functions 
    def dirA=(d); @dirA=d; end 
    def dirA; @dirA; end 
    def dirB=(d); @dirB=d; end 
    def dirB; @dirB; end 
end 

varA = A.new 
startT = 0 
dirT = 0 
accT = 0 

# now we do 100 times the same benchmarking 
# where we do the same assignment operation 
# 50000 times 
100.times do 
    startT = Time.now.to_f 
    50000.times do |i| 
    varA.dirA = i 
    varA.dirB = varA.dirA 
    end 
    dirT += (Time.now.to_f - startT) 

    startT = Time.now.to_f 
    50000.times do |i| 
    varA.acc = i 
    varA.bcc = varA.acc 
    end 
    accT += (Time.now.to_f - startT) 
end 

puts "direct: %10.4fs" % (dirT/100) 
puts "accessor: %10.4fs" % (accT/100) 

プログラムの出力です:

direct:  0.2640s 
accessor:  0.1927s 

のでattr_accessorが大幅に高速です。誰か知恵を分かち合うことができますか、なぜそうですか?

+3

ベンチマークコードの場合は、stdlibモジュールベンチマークを使用できます。http://www.ruby-doc.org/stdlib-1.9.3/libdoc/benchmark/rdoc/Benchmark.html#method-c-bm –

+0

ノートのThx。次回試してみるべきモジュールのように聞こえます。] – rhavin

答えて

10

違いを深く理解することなく、少なくともそのページのソースを切り替えることでわかるように、attr_accessor(とattr_readerattr_writer)がCで実装されていると言えます。あなたのメソッドはRubyで実装され、RubyメソッドはネイティブC関数より呼び出しオーバーヘッドが多くなります。

ここにはwhy Ruby method dispatch tends to be slowを説明する記事があります。

+0

リンク先は非常に有益です – rhavin

+0

よろしくお願いします。あなたがその質問に答えたと感じたら、その答えを受け入れるようにしてください。 – Brandan

関連する問題