Skip to content

Instantly share code, notes, and snippets.

@knowtheory
Created January 9, 2009 20:20
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 knowtheory/45259 to your computer and use it in GitHub Desktop.
Save knowtheory/45259 to your computer and use it in GitHub Desktop.
module Memoizer
def method_added(meth)
@_methods_to_memoize ||= []
@_methods_to_memoize << meth
end
def methods_to_memoize
@_methods_to_memoize
end
end
class Class
def memoize(kind = Hash, &blk)
memoizer = Module.new do
extend Memoizer
end
memoizer.class_eval(&blk)
self.send(:include, memoizer)
memoizer.methods_to_memoize.each do |meth|
arity = self.instance_method(meth).arity
if arity == 0
self.class_eval <<-RUBY
def #{meth}
@_memoized_#{meth} ||= super
end
RUBY
else
args = arity == 1 ? "args" : "*args"
self.class_eval <<-RUBY
def #{meth}(#{args})
@_memoized_#{meth} ||= #{kind}.new
@_memoized_#{meth}[args] ||= super
end
RUBY
end
end
end
end
class Foo
class << self
memoize do
def memoed(baz)
baz * 1000
end
end
def unmemoed(baz)
baz * 1000
end
end
def self.baseline(baz)
baz * 1000
end
memoize do
def memoed(baz)
baz * 1000
end
end
def unmemoed(baz)
baz * 1000
end
end
require 'benchmark'
n = 500
arr = [1,10,100,1000,10000]
Benchmark.bm do |x|
arr.each do |m|
x.report { n.times{Foo.memoed(m)} }
x.report { n.times{Foo.unmemoed(m)}}
x.report { n.times{Foo.baseline(m)}}
a_foo = Foo.new
x.report { n.times{a_foo.memoed(m)} }
x.report { n.times{a_foo.unmemoed(m)} }
puts "-----------------------------"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment