From: rafaelmfranca@... Date: 2015-08-19T03:13:26+00:00 Subject: [ruby-core:70453] [Ruby trunk - Bug #11461] [Open] Remove backtracing cleaning on Delegator methods Issue #11461 has been reported by Rafael Fran��a. ---------------------------------------- Bug #11461: Remove backtracing cleaning on Delegator methods https://bugs.ruby-lang.org/issues/11461 * Author: Rafael Fran��a * Status: Open * Priority: Normal * Assignee: Yukihiro Matsumoto * ruby -v: * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN ---------------------------------------- This improve the performance in 18 times when the delegated method raises some exception and in 15% for the success case. Here a benchmark result with a simpler script: (The backtrace have less than 10 items) require 'delegate' require 'benchmark/ips' class Foo def name 'foo' end def bla raise end end class Bar < DelegateClass(Foo) end bar = Bar.new(Foo.new) Benchmark.ips do |b| b.report('default') { bar.name } b.report('default raising') { bar.bla rescue nil } end Before this patch: $ ruby delegator_test.rb Calculating ------------------------------------- default 42.999k i/100ms default raising 1.456k i/100ms ------------------------------------------------- default 1.232M (�� 9.9%) i/s - 6.106M default raising 14.399k (��13.6%) i/s - 71.344k With this patch: $ ruby delegator_test.rb Calculating ------------------------------------- default 49.024k i/100ms default raising 19.308k i/100ms ------------------------------------------------- default 1.484M (�� 8.0%) i/s - 7.403M default raising 263.340k (�� 8.0%) i/s - 1.313M We could expect more performance difference in a huge application since their backtracers are bigger. This changes the output of the exception from: delegator_test.rb:18:in `bla': unhandled exception from delegator_test.rb:43:in `
' To: delegator_test.rb:18:in `bla': unhandled exception from /opt/ruby/lib/delegate.rb:340:in `block in delegating_block' from delegator_test.rb:43:in `
' This patch is important because Rails 4.2 use Delegator in some critical paths. From our production application this backtrace cleaner was one of the top 3 most CPU consuming calls. Here is the output of stackprof. block (2 levels) in Delegator.delegating_block (/usr/lib/shopify-ruby/2.1.6-shopify2/lib/ruby/2.1.0/delegate.rb:345) samples: 1228 self (5.2%) / 1228 total (5.2%) callers: 1228 ( 100.0%) block in Delegator.delegating_block code: 1228 (5.2%) / 1228 (5.2%) | 345 | $@.delete_if {|t| /\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:/o =~ t} if $@ | 346 | end Given the positive performance impact and that the difference of the backtrace output is not so big, I believe it is worth to consider removing the backtrace cleaner. ---Files-------------------------------- delegate.diff (1.22 KB) -- https://bugs.ruby-lang.org/