Module | Memoizable |
In: |
lib/facets/supplemental/facets/memoizable.rb
|
Memoization is an optimization technique used primarily to speed up programs by having function calls avoid repeating the calculation of results for previously-processed inputs.
When you "memoize" a method/function using Memoizable its results are cached so that later calls return results from the cache instead of recalculating them.
class T include Memoizable def initialize(a) @a = a end def a "#{@a ^ 3 + 4}" end memoize :a end t = T.new(10) (t.a.__id__ == t.a.__id__) #=> true
This method can also be used at the instance level to cache singleton (qua class) methods by including it in the singleton class.
# File lib/facets/supplemental/facets/memoizable.rb, line 44 def self.append_features(base) Module == base ? super(base) : base.extend(self) end
Directive for making your functions faster by trading space for time. When you "memoize" a method/function using memoize its results are cached so that later calls with the same arguments return results from the cache instead of recalculating them.
The memoize method also handles a few options to alter behavior of the memoization:
:class => true cache per-class not per-object :freeze => true freeze the memoized return values :arguments => false do not index cache by arguments
# File lib/facets/supplemental/facets/memoizable.rb, line 60 def memoize(*method_names) options = Hash === method_names.last ? method_names.pop : {} options[:arguments] = true if options[:arguments].nil? # default to true ref = options[:class] ? 'self.class.name' : 'self' frz = options[:freeze] ? '.freeze' : '' arg = options[:arguments] ? '[__a__, block_given?]' : 'nil' code = "" method_names.each do |m| code << "alias_method '\#{ m }:memo', '\#{ m }'\nprivate '\#{ m }:memo'\ndef \#{ m }(*__a__,&__b__)\nc = Memoizable.cache[\#{ref}][:'\#{ m }']\nk = \#{arg}\nif c.has_key?(k)\nc[k]\nelse\nc[k] = __send__('\#{ m }:memo',*__a__,&__b__)\#{frz}\nend\nend\n" end module_eval(code) end
Remove the memoized value from the memoization cache. The next time a memoized methos is called if will be remomoized.
# File lib/facets/supplemental/facets/memoizable.rb, line 92 def rememoize(*method_names) if Memoizable.cache[self] if method_names.empty? Memoizable.cache.delete(self) else method_names.each do |m| Memoizable.cache[self].delete(m.to_sym) end end end if Memoizable.cache[self.class.name] if method_names.empty? Memoizable.cache.delete(self.class.name) else method_names.each do |m| Memoizable.cache[self.class.name].delete(m.to_sym) end end end end