* lib/delegate.rb: Remove backtrace cleaning for delegated methods

This patch was provided by Rafael França and greatly improves
  performance when an exception is raised. [Bug #11461]

  Before:
    Calculating -------------------------------------
             default    86.209k i/100ms
     default raising     2.209k i/100ms
    -------------------------------------------------
             default      1.953M (±11.0%) i/s -      9.655M
     default raising     21.826k (±13.5%) i/s -    108.241k

  After:
    Calculating -------------------------------------
             default    72.211k i/100ms
     default raising    34.288k i/100ms
    -------------------------------------------------
             default      2.013M (±18.7%) i/s -      9.460M
     default raising    623.950k (± 9.7%) i/s -      3.120M

  Benchmark:
    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


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51806 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
zzak 2015-09-09 02:12:52 +00:00
parent 852c345470
commit 0a4129cb7a
2 changed files with 14 additions and 15 deletions

View File

@ -1,3 +1,9 @@
Wed Sep 9 11:08:59 2015 Zachary Scott <zzak@ruby-lang.org>
* lib/delegate.rb: Remove backtrace cleaning for delegated methods
This patch was provided by Rafael França and greatly improves
performance when an exception is raised. [Bug #11461]
Wed Sep 9 10:05:41 2015 SHIBATA Hiroshi <hsbt@ruby-lang.org>
* test/rubygems/test_config.rb: fix broken tests for Windows platform.

View File

@ -77,16 +77,13 @@ class Delegator < BasicObject
def method_missing(m, *args, &block)
r = true
target = self.__getobj__ {r = false}
begin
if r && target.respond_to?(m)
target.__send__(m, *args, &block)
elsif ::Kernel.respond_to?(m, true)
::Kernel.instance_method(m).bind(self).(*args, &block)
else
super(m, *args, &block)
end
ensure
$@.delete_if {|t| %r"\A#{Regexp.quote(__FILE__)}:(?:#{[__LINE__-7, __LINE__-5, __LINE__-3].join('|')}):"o =~ t} if $@
if r && target.respond_to?(m)
target.__send__(m, *args, &block)
elsif ::Kernel.respond_to?(m, true)
::Kernel.instance_method(m).bind(self).(*args, &block)
else
super(m, *args, &block)
end
end
@ -340,11 +337,7 @@ end
def Delegator.delegating_block(mid) # :nodoc:
lambda do |*args, &block|
target = self.__getobj__
begin
target.__send__(mid, *args, &block)
ensure
$@.delete_if {|t| /\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:/o =~ t} if $@
end
target.__send__(mid, *args, &block)
end
end