[ruby-dev:48816] [ruby-trunk - Bug #10470] TracePoint cannot trace attr_accessor/reader/writer method
From:
kakyoin.hierophant@...
Date:
2015-01-13 08:59:18 UTC
List:
ruby-dev #48816
Issue #10470 has been updated by Tomohiro Hashidate.
すいません。
元のサンプルコードを流用してしまったので、tracepointの性能測定としては余り適切じゃない感じのコードになってたことに気付きました。
~~~
trace = TracePoint.new(:return, :c_return) do |tp|
[tp.lineno, tp.defined_class, tp.method_id, tp.event, tp.binding, tp.return_value]
end
~~~
をもっとシンプルな形に変えて検証してみた場合、倍もパフォーマンスに違いは出ませんでした。
EXEC_EVENT_HOOKが無い場合はtp.binding等がそもそも呼ばれていないのでbindingを作る負荷が大分上乗せされてました…。
修正版とその結果を貼っておきます。
これでもEXEC_EVENT_HOOKがある場合は無い場合と比べてアクセサメソッド分のTracePointのインスタンスが生成されるのでその分の負荷が上乗せされることになります。
~~~
require 'benchmark/ips'
class Foo
attr_accessor :hoge
def bar
@bar
end
def initialize(val)
@bar = val
end
end
foo = Foo.new("FOO")
trace = TracePoint.new(:return, :c_return) do |tp|
tp
end
Benchmark.ips do |x|
x.report("tracing access") do |time|
trace.enable do
foo.bar
foo.hoge = "hoge#{time}"
foo.hoge
end
end
end
~~~
### trace.enable EXEC_EVENT_HOOK無し
~~~
Calculating -------------------------------------
tracing access 59.598k i/100ms
-------------------------------------------------
tracing access 47.489B (±36.5%) i/s - 103.366B
~~~
### trace.enable EXEC_EVENT_HOOK有り
~~~
Calculating -------------------------------------
tracing access 55.833k i/100ms
-------------------------------------------------
tracing access 39.855B (±41.0%) i/s - 87.620B
~~~
----------------------------------------
Bug #10470: TracePoint cannot trace attr_accessor/reader/writer method
https://bugs.ruby-lang.org/issues/10470#change-50975
* Author: Tomohiro Hashidate
* Status: Assigned
* Priority: Normal
* Assignee: Koichi Sasada
* ruby -v: ruby 2.2.0dev (2014-11-01 trunk 48219) [x86_64-darwin13]
* Backport: 2.0.0: REQUIRED, 2.1: REQUIRED
----------------------------------------
TracePointを利用して`attr_accessor`で定義したメソッドの`:c_call`, `:c_return`イベントを取得することができません。
```ruby
class Foo
attr_accessor :hoge
def bar
@bar
end
def initialize(val)
@bar = val
end
end
foo = Foo.new("FOO")
trace = TracePoint.new(:return, :c_return) do |tp|
p [tp.lineno, tp.defined_class, tp.method_id, tp.event, tp.binding, tp.return_value]
end
trace.enable do
foo.bar
foo.hoge = "hoge"
foo.hoge
end
```
上記のコードを実行した時、attr_accessorで定義した`hoge`メソッドのイベントが発生しません。
調査した所、`EXEC_EVENT_HOOK`の呼び出し自体が無いようです。
このため、例えばpower_assertを利用した時にアクセサメソッドの戻り値を取得できない等の問題が発生します。
attributeの読み書きを行う処理の中に`EXEC_EVENT_HOOK`を呼び出す簡単なパッチを書きましたので、添付します。
---Files--------------------------------
fix_attr_accessor_event.diff (1.98 KB)
--
https://bugs.ruby-lang.org/