mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix performance slowdown in Ruby 2.7+
In #34068 I introduced code that improved performance in Ruby 2.5. But recently @Jeremyevans pointed out that it made code slower in 2.7+ which Rails targets https://gist.github.com/jeremyevans/40675ac1f69b4ac405d3c6ba060cdd35. Here's the twitter thread https://twitter.com/jeremyevans0/status/1414731600693108737. This change essentially reverts #34068 ``` $ cat scratch.rb class FooCurrent def try(_method_name = nil, *) nil end end class FooUpdated def try(*) nil end end require 'benchmark/ips' foo_updated = FooUpdated.new foo_current = FooCurrent.new Benchmark.ips do |x| x.report("updated") { foo_updated.try(:anything) } x.report("current") { foo_current.try(:anything) } x.compare! end $ ruby -v ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin19] $ ruby scratch.rb Warming up -------------------------------------- updated 854.461k i/100ms current 687.183k i/100ms Calculating ------------------------------------- updated 8.418M (± 2.1%) i/s - 42.723M in 5.077403s current 6.619M (± 9.6%) i/s - 32.985M in 5.048477s Comparison: updated: 8418315.3 i/s current: 6619074.1 i/s - 1.27x (± 0.00) slower ```
This commit is contained in:
parent
359efef64b
commit
bb513b8541
1 changed files with 9 additions and 9 deletions
|
@ -4,28 +4,28 @@ require "delegate"
|
|||
|
||||
module ActiveSupport
|
||||
module Tryable #:nodoc:
|
||||
def try(method_name = nil, *args, &block)
|
||||
if method_name.nil? && block_given?
|
||||
def try(*args, &block)
|
||||
if args.empty? && block_given?
|
||||
if block.arity == 0
|
||||
instance_eval(&block)
|
||||
else
|
||||
yield self
|
||||
end
|
||||
elsif respond_to?(method_name)
|
||||
public_send(method_name, *args, &block)
|
||||
elsif respond_to?(args.first)
|
||||
public_send(*args, &block)
|
||||
end
|
||||
end
|
||||
ruby2_keywords(:try)
|
||||
|
||||
def try!(method_name = nil, *args, &block)
|
||||
if method_name.nil? && block_given?
|
||||
def try!(*args, &block)
|
||||
if args.empty? && block_given?
|
||||
if block.arity == 0
|
||||
instance_eval(&block)
|
||||
else
|
||||
yield self
|
||||
end
|
||||
else
|
||||
public_send(method_name, *args, &block)
|
||||
public_send(*args, &block)
|
||||
end
|
||||
end
|
||||
ruby2_keywords(:try!)
|
||||
|
@ -145,14 +145,14 @@ class NilClass
|
|||
#
|
||||
# With +try+
|
||||
# @person.try(:children).try(:first).try(:name)
|
||||
def try(_method_name = nil, *)
|
||||
def try(*)
|
||||
nil
|
||||
end
|
||||
|
||||
# Calling +try!+ on +nil+ always returns +nil+.
|
||||
#
|
||||
# nil.try!(:name) # => nil
|
||||
def try!(_method_name = nil, *)
|
||||
def try!(*)
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue