Skip to content

Instantly share code, notes, and snippets.

@dasch
Created August 29, 2011 10:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dasch/1178156 to your computer and use it in GitHub Desktop.
Save dasch/1178156 to your computer and use it in GitHub Desktop.
Delegation Benchmarks
#
# A benchmark testing the performance of three methods of delegation:
#
# - Manually defining delegation methods
# - Metaprogramming using __send__
# - Metaprogramming without using __send__
#
# Note that the manual way of doing it is much faster if the arity of the
# target method is known. However, this benchmark is only meant to test
# the issue of __send__, and so we define the delegation methods with
# variable arguments.
require 'benchmark'
class Module
def new_delegate(target, method)
class_eval(<<-RUBY)
def #{method}(*args, &block)
#{target}.#{method}(*args, &block)
end
RUBY
end
def old_delegate(target, method)
class_eval(<<-RUBY)
def #{method}(*args, &block)
#{target}.__send__(:#{method}, *args, &block)
end
RUBY
end
end
class Target
def hello(a, b, c); 'world'; end
end
class TargetWrapper
def initialize
@target = Target.new
end
end
class MethodDelegate < TargetWrapper
def hello(*args); @target.hello(*args); end
end
class OldDelegate < TargetWrapper
old_delegate :@target, :hello
end
class NewDelegate < TargetWrapper
new_delegate :@target, :hello
end
n = 10_000_000
method = MethodDelegate.new
old = OldDelegate.new
new = NewDelegate.new
Benchmark.bm(7) do |x|
x.report('method') { n.times { method.hello(1, 2, 3) } }
x.report('old') { n.times { old.hello(1, 2, 3) } }
x.report('new') { n.times { new.hello(1, 2, 3) } }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment