Module: Memoize
- Defined in:
- lib/memoize.rb
Overview
Memoize is implementation Memoization for Ruby, this techinique to make functions faster.
Caveats:
-
Do not memoize a function whose behaviou depends on program state.
-
Do not memoize a function with side effects.
-
Do not memoize a function that returns a data structure that is modified by it’s caller.
See:
Memoization - en.wikipedia.org/wiki/Memoization
Defined Under Namespace
Modules: Expire Classes: MemoryStore, PStore, Storable
Constant Summary collapse
- VERSION =
'0.1.0'
- @@stores =
{}
Class Method Summary collapse
-
._get_store(name) ⇒ Object
This method is public, but you don’t need call directly.
-
._set_store(name, store) ⇒ Object
This method is public, but you don’t need call directly.
-
.register(klass, name, options = {}) ⇒ Object
Make memoized function.
-
.unmemoize(klass, name, delete_all = false) ⇒ Object
Specify unmemoize method.
Class Method Details
._get_store(name) ⇒ Object
This method is public, but you don’t need call directly.
248 249 250 |
# File 'lib/memoize.rb', line 248 def _get_store(name) @@stores[name] end |
._set_store(name, store) ⇒ Object
This method is public, but you don’t need call directly.
243 244 245 |
# File 'lib/memoize.rb', line 243 def _set_store(name, store) @@stores[name] = store end |
.register(klass, name, options = {}) ⇒ Object
Make memoized function.
Parameters:
-
klass - You must surely specify ‘self’. This parameter used to overwrite Toplevell function and
register as toplevel function. I need to think better the means ;)
-
name - an memorized function name.
-
options - an specify options.
:as
is memorized function name, default is the same second arguments value.<tt>:store</tt> is specify class which store memorized data.
Memoized function examples
def fib(n)
return 1 if n < 2
fib(n-1) + fib(n-2)
end
end
Memoize.register(self, 'fib')
fib(30) # => 1346269 fast
fib(30) # => 1346269 very fast
# Unmemorize
Memoize.unmemoize(self, 'fib')
fib(30) # => very slow
Memoized one Object methods
class Math2
def self.fib(N)
return 1 if n < 2
fib(n-1) + fib(n-2)
end
end
Memoize.memorize(self, 'Math2.fib')
Math.fib(30) # => fast
Math.fib(30) # => very fast
Memoize.unmemoize(self, 'Math2.fib')
Custom storage
You can use own memoized data storage, in doing so you must implementaion following method
Method/Arity:
-
initialize/1 - this is constructor
-
get/1 - an get the cache data with key
-
set/2 - an set the cache data with key and value
-
delete/1 - an delete the cache data with key
-
delete_all/0 - an delete all cache
Following class is MemCache storage sample.
# Memoized data storage using MemCache
require 'memcache'
class MemCacheStore < Memoize::Storable
attr_accessor :cache, :keys
def initialize(name)
@keys = []
@cache = MemCache.new 'localhost:11211', :namespace => 'rakuto.blogspot.com'
end
def get(key)
@cache.get(key)
end
def set(key, value)
@keys << key unless @keys.include?(key)
@cache.set(key, value)
end
def delete(key)
@cache.delete(key)
end
def delete_all
@keys.each { |key| @cache.delete(key) }
end
end
Memoize.register(self, 'fib', :store => MemCacheStore)
fib(30) # => fast
fib(30) # => fast
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/memoize.rb', line 203 def register(klass, name, ={}) ns = name.split(/::|\./) method, klass = ns.pop, (ns.empty? ? klass : Object.const_get(ns.join("::"))) store = [:store].nil? ? PStore.new(name) : [:store].new(name) as_method = [:as] || method Memoize._set_store(name, store) (class<<klass;self;end).instance_eval do # for Ruby1.9 method_name = "#{as_method}_without_memoize" memoized_method_name = "#{as_method}_with_memoize" define_method(memoized_method_name) do |*args| store = Memoize._get_store(name) ret = store.get(args) if ret.nil? ret = send(method_name, *args) store.set(args, ret) end ret end alias_method method_name, method alias_method as_method, memoized_method_name end end |
.unmemoize(klass, name, delete_all = false) ⇒ Object
234 235 236 237 238 239 240 |
# File 'lib/memoize.rb', line 234 def unmemoize(klass, name, delete_all=false) (class<<klass;self;end).class_eval do undef_method("#{name}_with_memoize") alias_method name, "#{name}_without_memoize" end delete_all && @store.delete_all end |