11

attr_accessorを同等のgetter/setter-methodsに対してテストしました。

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は大幅に高速です。誰かがいくつかの知恵を共有してくれませんか、なぜそうなのですか?

4

1 に答える 1

13

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

これは、Rubyメソッドのディスパッチが遅くなる傾向がある理由を説明する記事です。

于 2012-11-21T13:38:35.430 に答える