aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
authorschneems <richard.schneeman+foo@gmail.com>2018-08-28 21:27:21 -0500
committerschneems <richard.schneeman+foo@gmail.com>2018-08-29 10:03:48 -0500
commitba7d1265e3f2755f55243f32c0264c5c20e01610 (patch)
tree2411f0287759de5f8c1cb4ce08b78bb08fc29c60 /activesupport/lib
parentb7294944547c984bb92864493435b516e68bd623 (diff)
downloadrails-ba7d1265e3f2755f55243f32c0264c5c20e01610.tar.gz
rails-ba7d1265e3f2755f55243f32c0264c5c20e01610.tar.bz2
rails-ba7d1265e3f2755f55243f32c0264c5c20e01610.zip
32% Faster Object#try
Here’s the micro benchmark: ```ruby module ActiveSupport module NewTryable #:nodoc: def try(*a, &b) return unless a.empty? || respond_to?(a.first) return public_send(*a, &b) unless a.empty? return nil unless block_given? return instance_eval(&b) if b.arity == 0 yield self end def try!(*a, &b) return public_send(*a, &b) if !a.empty? return nil unless block_given? return instance_eval(&b) if b.arity == 0 yield self end end end module ActiveSupport module OldTryable #:nodoc: def try(*a, &b) try!(*a, &b) if a.empty? || respond_to?(a.first) end def try!(*a, &b) if a.empty? && block_given? if b.arity == 0 instance_eval(&b) else yield self end else public_send(*a, &b) end end end end class FooNew include ActiveSupport::NewTryable def foo end end class FooOld include ActiveSupport::OldTryable def foo end end foo_new = FooNew.new foo_old = FooOld.new require 'benchmark/ips' Benchmark.ips do |x| x.report("old") { foo_old.try(:foo) } x.report("new") { foo_new.try(:foo) } x.compare! end # Warming up -------------------------------------- # old 144.178k i/100ms # new 172.371k i/100ms # Calculating ------------------------------------- # old 2.181M (± 8.0%) i/s - 10.813M in 5.001419s # new 2.889M (± 7.7%) i/s - 14.479M in 5.051760s # Comparison: # new: 2888691.7 i/s # old: 2180740.7 i/s - 1.32x slower ``` Also reduces memory. On https://www.codetriage.com i’m seeing 1.5% fewer object allocations per request (in object count). Before: Total allocated: 1014475 bytes (8525 objects) After: Total allocated: 1015499 bytes (8389 objects)
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support/core_ext/object/try.rb11
1 files changed, 10 insertions, 1 deletions
diff --git a/activesupport/lib/active_support/core_ext/object/try.rb b/activesupport/lib/active_support/core_ext/object/try.rb
index c874691629..bd841771ce 100644
--- a/activesupport/lib/active_support/core_ext/object/try.rb
+++ b/activesupport/lib/active_support/core_ext/object/try.rb
@@ -5,7 +5,16 @@ require "delegate"
module ActiveSupport
module Tryable #:nodoc:
def try(*a, &b)
- try!(*a, &b) if a.empty? || respond_to?(a.first)
+ return unless a.empty? || respond_to?(a.first)
+ if a.empty? && block_given?
+ if b.arity == 0
+ instance_eval(&b)
+ else
+ yield self
+ end
+ else
+ public_send(*a, &b)
+ end
end
def try!(*a, &b)