Skip to content

Instantly share code, notes, and snippets.

@ivopt
Last active July 16, 2019 09:15
Show Gist options
  • Save ivopt/22561894ade1a51560a7eabf70f05fec to your computer and use it in GitHub Desktop.
Save ivopt/22561894ade1a51560a7eabf70f05fec to your computer and use it in GitHub Desktop.
WoW, SimpleDelegator is REALLY slow...
require 'benchmark'
require 'active_support/core_ext/module/delegation'
# 6! = 720
METHODS = %w[a b c d e f].permutation.map(&:join)
class Decoratee
METHODS.each do |m|
define_method m do
m
end
end
end
class SimpleDecorator
def initialize(object)
@object = object
end
protected
attr_reader :object
class << self
def auto_delegate(*methods)
delegate(*methods, to: :object)
end
end
end
class Decorated < SimpleDecorator
def abcdef
object.abcdef
end
end
class DelegatedDecorated < SimpleDecorator
auto_delegate :abcdef
end
class Delegated < SimpleDelegator
def xpto
abcdef
end
def xptz
__getobj__.abcdef
end
end
class Missing
def initialize(obj)
@obj = obj
end
def responds_to?(method)
@obj.responds_to?(method)
end
def method_missing(method, *args)
@obj.send(method, *args)
end
end
class SmartMissing
def initialize(obj)
@obj = obj
end
def respond_to_missing?(method)
@obj.respond_to?(method)
end
def method_missing(method, *args)
if respond_to_missing?(method)
self.class.class_eval <<~RUBY
def #{method}(*args)
@obj.#{method}(*args)
end
RUBY
end
@obj.send(method, *args)
end
end
TESTS = 10_000_000
decoratee = Decoratee.new
decorated = Decorated.new(decoratee)
delegated_decorated = DelegatedDecorated.new(decoratee)
delegated = Delegated.new(decoratee)
missing = Missing.new(decoratee)
smartmissing = SmartMissing.new(decoratee)
Benchmark.bm do |x|
x.report('Baseline: ') { TESTS.times { decoratee.abcdef } }
x.report('SimpleDecorator - method ') { TESTS.times { decorated.abcdef } }
x.report('SimpleDecorator - delegation: ') { TESTS.times { delegated_decorated.abcdef } }
x.report('SimpleDelegator - method: ') { TESTS.times { delegated.xptz } }
x.report('SimpleDelegator - method w/ delegation: ') { TESTS.times { delegated.xpto } }
x.report('SimpleDelegator - delegation: ') { TESTS.times { delegated.abcdef } }
x.report('MethodMissing - simple mm: ') { TESTS.times { missing.abcdef } }
x.report('MethodMissing - smart mm: ') { TESTS.times { smartmissing.abcdef } }
end
user system total real
Baseline: 0.875386 0.000259 0.875645 ( 0.875677)
SimpleDecorator - method 1.311704 0.000217 1.311921 ( 1.311985)
SimpleDecorator - delegation: 2.043516 0.000587 2.044103 ( 2.044270)
SimpleDelegator - method: 1.371788 0.000402 1.372190 ( 1.372431)
SimpleDelegator - method w/ delegation: 3.280072 0.000998 3.281070 ( 3.281436)
SimpleDelegator - delegation: 3.125444 0.001395 3.126839 ( 3.127281)
MethodMissing - simple mm: 2.132746 0.000728 2.133474 ( 2.133660)
MethodMissing - smart mm: 1.555830 0.000233 1.556063 ( 1.556142)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment