Created
November 20, 2013 00:40
-
-
Save rbishop/7555357 to your computer and use it in GitHub Desktop.
Disclaimer: Yes, this is performance testing and Ruby. Obviously we choose Ruby for it's other greater qualities. Playing around with performance regarding the various ways you can implement Decorators in Ruby.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark' | |
require 'delegate' | |
require 'forwardable' | |
class Person | |
def initialize(name) | |
@name = name | |
end | |
def name | |
@name | |
end | |
end | |
class PersonDelegator < SimpleDelegator | |
def initialize(person) | |
super(person) | |
end | |
end | |
class PersonForwarder | |
extend Forwardable | |
def_delegator :@person, :name | |
def initialize(person) | |
@person = person | |
end | |
end | |
class PersonMissing | |
def method_missing(method_name) | |
if @person.respond_to?(method_name) | |
@person.send(method_name) | |
else | |
super | |
end | |
end | |
def initialize(person) | |
@person = person | |
end | |
end | |
bob = Person.new('Bob') | |
decorated_bob = PersonDelegator.new(bob) | |
forwarded_bob = PersonForwarder.new(bob) | |
missing_bob = PersonMissing.new(bob) | |
Benchmark.bmbm do |bm| | |
bm.report('Sending message directly') do | |
1_000_000.times do | |
bob.name | |
end | |
end | |
bm.report 'Sending message through SimpleDelegator' do | |
1_000_000.times do | |
decorated_bob.name | |
end | |
end | |
bm.report 'Forwarding message using Forwardable' do | |
1_000_000.times do | |
forwarded_bob.name | |
end | |
end | |
bm.report 'Sending message using method_missing' do | |
1_000_000.times do | |
missing_bob.name | |
end | |
end | |
end | |
# Sending message directly 0.090000 0.000000 0.090000 ( 0.086165) | |
# Sending message through SimpleDelegator 0.410000 0.000000 0.410000 ( 0.410749) | |
# Forwarding message using Forwardable 0.230000 0.000000 0.230000 ( 0.233133) | |
# Sending message using method_missing 0.260000 0.000000 0.260000 ( 0.254218) | |
# ------------------------------------------------------------------ total: 0.990000sec | |
user system total real | |
# Sending message directly 0.080000 0.000000 0.080000 ( 0.080132) | |
# Sending message through SimpleDelegator 0.400000 0.000000 0.400000 ( 0.403982) | |
# Forwarding message using Forwardable 0.230000 0.000000 0.230000 ( 0.228633) | |
# Sending message using method_missing 0.250000 0.000000 0.250000 ( 0.251649) |
Very interesting results !!
I added another case: subclassing the class (and is almost as fast as the original one).
Rehearsal ---------------------------------------------------------------------------
Sending message directly 0.050000 0.000000 0.050000 ( 0.055301)
Sending message through SimpleDelegator 0.280000 0.000000 0.280000 ( 0.280395)
Forwarding message using Forwardable 0.150000 0.000000 0.150000 ( 0.150432)
Sending message using method_missing 0.160000 0.000000 0.160000 ( 0.157218)
Sending message using subclassing 0.050000 0.000000 0.050000 ( 0.052206)
------------------------------------------------------------------ total: 0.690000sec
user system total real
Sending message directly 0.050000 0.000000 0.050000 ( 0.050754)
Sending message through SimpleDelegator 0.280000 0.000000 0.280000 ( 0.279871)
Forwarding message using Forwardable 0.160000 0.000000 0.160000 ( 0.152889)
Sending message using method_missing 0.150000 0.000000 0.150000 ( 0.152737)
Sending message using subclassing 0.050000 0.000000 0.050000 ( 0.051002)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In 2015, newer ruby, faster CPU, similar differences.
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin15]