GIGO: words unreadable aloud
Mishrogo Weedapeval
 

 

  Wednesday 9 November 2005
Cheap Ruby memoize using Hash default block

As MenTaLguY mentioned, you can give a block to Hash.new in Ruby. This leads to pretty simple memoization. E.g.,

# Demonstrate a "memoizing" behavior of certain Hash usage
def fib_n ( n )
    if n <= 1
        n
    else
        fib_n( n-1 ) + fib_n( n-2 )
    end
end
$fib_mh = Hash.new do |h,n|
        if n <= 1
            h[n] = n
        else
            h[n] = fib_m( n-1 ) + fib_m( n-2 )
        end
    end
def fib_m ( n )
    $fib_mh[ n ]
end
def compar (lim)
    # puts lim
    strt = Time.now
    puts fib_n(lim)
    mid = Time.now
    puts fib_m(lim)
    last= Time.now
    puts "Lim(#{lim}), no memoing, takes #{mid-strt} seconds."
    puts "Lim(#{lim}), memoing, takes #{last-mid} seconds."
end
compar( ARGV[0].to_i )

Unless you have a lot of time, don't try running this with an argument bigger than the mid-30s.

The RAA has a memoize mixin, but it doesn't use quite the same trick. It's still pretty short, though. The guts:

module Memoize
   MEMOIZE_VERSION = "1.1.0"
   def memoize(name)
      meth = method(name)
      cache = {}
      (class << self; self; end).class_eval do
         define_method(name) do |*args|
            cache.has_key?(args) ? cache[args] : cache[args] ||= meth.call(*args)
         end
      end
      cache
   end
end

11:56:34 PM   comment/     


Click here to visit the Radio UserLand website. Click to see the XML version of this web page. © Copyright 2007 Doug Landauer .
Last update: 07/2/7; 21:39:40 .
Click here to send an email to the editor of this weblog.

November 2005
Sun Mon Tue Wed Thu Fri Sat
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30      
Oct   Dec

Previous/Next