Skip to content

Instantly share code, notes, and snippets.

@egonSchiele
Created March 4, 2013 23:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save egonSchiele/5086572 to your computer and use it in GitHub Desktop.
Save egonSchiele/5086572 to your computer and use it in GitHub Desktop.
Time difference between wrapped methods and regular methods
require 'benchmark'
module Wrapper
def self.extended(klass)
klass.class_eval do
@@methods = {}
def self.methods
@@methods
end
def self.set_method k, v
@@methods[k] = v
end
end
end
def method_added name
return if methods.include?(name)
puts "#{name} added"
set_method(name, instance_method(name))
class_eval %{
def #{name}(*args)
self.class.methods[#{name.inspect}].bind(self).call(*args)
end
}, __FILE__, __LINE__ + 1
end
end
module Wrapper2
def self.extended(klass)
klass.class_eval do
@@methods = []
def self.methods
@@methods
end
def self.add_method name
@@methods << name
end
end
end
def method_added name
return if methods.include?(name) || name =~ /original/
puts "#{name} added2"
add_method(name)
alias_method :"original_#{name}", name
define_method name do |*args|
self.send :"original_#{name}", *args
end
end
end
class NotWrapped
def add a, b
a + b
end
end
class Wrapped
extend ::Wrapper
def add a, b
a + b
end
end
class Wrapped2
extend ::Wrapper2
def add a, b
a + b
end
end
w = Wrapped.new
w2 = Wrapped2.new
nw = NotWrapped.new
Benchmark.bm 30 do |x|
x.report 'wrapped w/ method reference' do
1000000.times do |_|
w.add(rand(1000), rand(1000))
end
end
x.report 'wrapped w/ alias_method' do
1000000.times do |_|
w2.add(rand(1000), rand(1000))
end
end
x.report 'not wrapped' do
1000000.times do |_|
nw.add(rand(1000), rand(1000))
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment