Skip to content

Instantly share code, notes, and snippets.

@jrunning
Last active December 10, 2015 23:30
Show Gist options
  • Select an option

  • Save jrunning/0e18236c6363af15c520 to your computer and use it in GitHub Desktop.

Select an option

Save jrunning/0e18236c6363af15c520 to your computer and use it in GitHub Desktop.
rescue-vs-respond-to.rb
require 'benchmark/ips'
module RescueVsRespondTo
module HelperClasses
class Receiver
def dummy; true end
def does_exist; true end
end
class Great20Grandparent < Receiver; end
class Great19Grandparent < Great20Grandparent; end
class Great18Grandparent < Great19Grandparent; end
class Great17Grandparent < Great18Grandparent; end
class Great16Grandparent < Great17Grandparent; end
class Great15Grandparent < Great16Grandparent; end
class Great14Grandparent < Great15Grandparent; end
class Great13Grandparent < Great14Grandparent; end
class Great12Grandparent < Great13Grandparent; end
class Great11Grandparent < Great12Grandparent; end
class Great10Grandparent < Great11Grandparent; end
class Great9Grandparent < Great10Grandparent; end
class Great8Grandparent < Great9Grandparent; end
class Great7Grandparent < Great8Grandparent; end
class Great6Grandparent < Great7Grandparent; end
class Great5Grandparent < Great6Grandparent; end
class Great4Grandparent < Great5Grandparent; end
class Great3Grandparent < Great4Grandparent; end
class Great2Grandparent < Great3Grandparent; end
class GreatGrandparent < Great2Grandparent; end
class Grandparent < GreatGrandparent; end
class Parent < Grandparent; end
class DeepReceiver < Parent; end
end
class LocalVariableOrMethod
def dummy; true end
def does_exist; true end
def test_rescue_does_exist
does_exist
rescue
dummy
end
def test_rescue_doesnt_exist
doesnt_exist
rescue
dummy
end
def test_respond_to_does_exist
if respond_to?(:does_exist)
does_exist
else
dummy
end
end
def test_respond_to_doesnt_exist
if respond_to?(:doesnt_exist)
doesnt_exist
else
dummy
end
end
end
class ExplicitReceiver
def initialize
@receiver = HelperClasses::Receiver.new
end
def test_rescue_does_exist
@receiver.does_exist
rescue
@receiver.dummy
end
def test_rescue_doesnt_exist
@receiver.doesnt_exist
rescue
@receiver.dummy
end
def test_respond_to_does_exist
if @receiver.respond_to?(:does_exist)
@receiver.does_exist
else
@receiver.dummy
end
end
def test_respond_to_doesnt_exist
if @receiver.respond_to?(:doesnt_exist)
@receiver.doesnt_exist
else
@receiver.dummy
end
end
end
class LongInheritanceChain < ExplicitReceiver
def initialize
@receiver = HelperClasses::DeepReceiver.new
end
end
end
def global_dummy; true end
def global_does_exist; true end
def test_rescue_global_does_exist
global_does_exist
rescue
global_dummy
end
def test_rescue_global_doesnt_exist
global_doesnt_exist
rescue
global_dummy
end
def test_respond_to_global_does_exist
if respond_to?(:does_exist)
global_does_exist
else
global_dummy
end
end
def test_respond_to_global_doesnt_exist
if respond_to?(:doesnt_exist)
global_doesnt_exist
else
global_dummy
end
end
Benchmark.ips do |x|
%w[ LocalVariableOrMethod ExplicitReceiver LongInheritanceChain ].each do |class_name|
subject = RescueVsRespondTo.const_get(class_name).new
x.report("#{class_name}#test_rescue_does_exist") { subject.test_rescue_does_exist }
x.report("#{class_name}#test_rescue_doesnt_exist") { subject.test_rescue_doesnt_exist }
x.report("#{class_name}#test_respond_to_does_exist") { subject.test_respond_to_does_exist }
x.report("#{class_name}#test_respond_to_doesnt_exist") { subject.test_respond_to_doesnt_exist }
end
x.report("test_rescue_global_does_exist") { test_rescue_global_does_exist }
x.report("test_rescue_global_doesnt_exist") { test_rescue_global_doesnt_exist }
x.report("test_respond_to_global_does_exist") { test_respond_to_global_does_exist }
x.report("test_respond_to_global_doesnt_exist") { test_respond_to_global_doesnt_exist }
x.compare!
end
$ ruby -v rescue-vs-respond-to.rb
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin15]
Calculating -------------------------------------
LocalVariableOrMethod#test_rescue_does_exist
153.478k i/100ms
LocalVariableOrMethod#test_rescue_doesnt_exist
36.693k i/100ms
LocalVariableOrMethod#test_respond_to_does_exist
139.936k i/100ms
LocalVariableOrMethod#test_respond_to_doesnt_exist
136.213k i/100ms
ExplicitReceiver#test_rescue_does_exist
147.227k i/100ms
ExplicitReceiver#test_rescue_doesnt_exist
32.197k i/100ms
ExplicitReceiver#test_respond_to_does_exist
137.546k i/100ms
ExplicitReceiver#test_respond_to_doesnt_exist
131.152k i/100ms
LongInheritanceChain#test_rescue_does_exist
147.703k i/100ms
LongInheritanceChain#test_rescue_doesnt_exist
32.647k i/100ms
LongInheritanceChain#test_respond_to_does_exist
140.061k i/100ms
LongInheritanceChain#test_respond_to_doesnt_exist
132.879k i/100ms
test_rescue_global_does_exist
149.804k i/100ms
test_rescue_global_doesnt_exist
35.270k i/100ms
test_respond_to_global_does_exist
133.853k i/100ms
test_respond_to_global_doesnt_exist
131.175k i/100ms
-------------------------------------------------
LocalVariableOrMethod#test_rescue_does_exist
6.889M (± 6.9%) i/s - 34.379M
LocalVariableOrMethod#test_rescue_doesnt_exist
433.941k (± 7.9%) i/s - 2.165M
LocalVariableOrMethod#test_respond_to_does_exist
5.072M (± 6.8%) i/s - 25.328M
LocalVariableOrMethod#test_respond_to_doesnt_exist
4.362M (± 7.2%) i/s - 21.794M
ExplicitReceiver#test_rescue_does_exist
6.652M (± 9.8%) i/s - 32.684M
ExplicitReceiver#test_rescue_doesnt_exist
390.686k (± 5.7%) i/s - 1.964M
ExplicitReceiver#test_respond_to_does_exist
4.710M (±10.1%) i/s - 23.245M
ExplicitReceiver#test_respond_to_doesnt_exist
4.198M (±10.2%) i/s - 20.591M
LongInheritanceChain#test_rescue_does_exist
7.021M (± 5.7%) i/s - 35.006M
LongInheritanceChain#test_rescue_doesnt_exist
401.436k (± 4.1%) i/s - 2.024M
LongInheritanceChain#test_respond_to_does_exist
4.875M (± 5.5%) i/s - 24.371M
LongInheritanceChain#test_respond_to_doesnt_exist
4.242M (± 6.8%) i/s - 21.128M
test_rescue_global_does_exist
7.199M (± 5.8%) i/s - 35.953M
test_rescue_global_doesnt_exist
440.868k (± 7.2%) i/s - 2.222M
test_respond_to_global_does_exist
4.477M (± 8.7%) i/s - 22.086M
test_respond_to_global_doesnt_exist
4.494M (± 5.6%) i/s - 22.431M
Comparison:
test_rescue_global_does_exist: 7198903.1 i/s
LongInheritanceChain#test_rescue_does_exist: 7020856.7 i/s - 1.03x slower
LocalVariableOrMethod#test_rescue_does_exist: 6889267.6 i/s - 1.04x slower
ExplicitReceiver#test_rescue_does_exist: 6652320.0 i/s - 1.08x slower
LocalVariableOrMethod#test_respond_to_does_exist: 5071518.2 i/s - 1.42x slower
LongInheritanceChain#test_respond_to_does_exist: 4875481.1 i/s - 1.48x slower
ExplicitReceiver#test_respond_to_does_exist: 4710240.7 i/s - 1.53x slower
test_respond_to_global_doesnt_exist: 4493565.9 i/s - 1.60x slower
test_respond_to_global_does_exist: 4476828.4 i/s - 1.61x slower
LocalVariableOrMethod#test_respond_to_doesnt_exist: 4361534.9 i/s - 1.65x slower
LongInheritanceChain#test_respond_to_doesnt_exist: 4242077.8 i/s - 1.70x slower
ExplicitReceiver#test_respond_to_doesnt_exist: 4197999.7 i/s - 1.71x slower
test_rescue_global_doesnt_exist: 440868.3 i/s - 16.33x slower
LocalVariableOrMethod#test_rescue_doesnt_exist: 433941.1 i/s - 16.59x slower
LongInheritanceChain#test_rescue_doesnt_exist: 401436.4 i/s - 17.93x slower
ExplicitReceiver#test_rescue_doesnt_exist: 390686.3 i/s - 18.43x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment