Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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.
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)
@rhulse
Copy link

rhulse commented Oct 25, 2015

In 2015, newer ruby, faster CPU, similar differences.

ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin15]

# Rehearsal ---------------------------------------------------------------------------
# Sending message directly                  0.070000   0.000000   0.070000 (  0.078030)
# Sending message through SimpleDelegator   0.380000   0.000000   0.380000 (  0.382877)
# Forwarding message using Forwardable      0.190000   0.000000   0.190000 (  0.200241)
# Sending message using method_missing      0.210000   0.000000   0.210000 (  0.210172)
------------------------------------------------------------------ total: 0.850000sec

#                                              user     system      total        real
# Sending message directly                  0.070000   0.000000   0.070000 (  0.077865)
# Sending message through SimpleDelegator   0.370000   0.000000   0.370000 (  0.377200)
# Forwarding message using Forwardable      0.200000   0.010000   0.210000 (  0.202917)
# Sending message using method_missing      0.200000   0.000000   0.200000 (  0.208708)

@vasilakisfil
Copy link

vasilakisfil commented Dec 21, 2017

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