La memoizacion es una técnica que se usa para acelerar el cómputo de una función cuando:
En esta sección aumentamos el módulo Functional
con el operador unario
+lambda
que retorna una lambda equivalente a su argumento
pero que cachea la relación entre argumentos y el valor retornado.
Veamos un ejemplo de uso. Las circustancias enumeradas anteriormente se dan en el cálculo de la función de Fibonacci.
Arbol de llamadas para la función de Fibonacci
require './functional_partial' require 'benchmark' .... if $0 == __FILE__ fib = lambda { |n| n < 2 ? n : fib[n-1] + fib[n-2] } fibm = +fib n = 35 Benchmark.benchmark(CAPTION, 7, FORMAT) do |x| tf = x.report("computed:") { fib[n] } tt = x.report("memoized:") { fibm[n] } end endLa ejecución compara las dos versiones, con y sin memoizar:
[~/TheRubyProgrammingLanguage/Chapter6MethodsProcsLambdasAndClosures]$ ruby functional_memoize.rb user system total real computed: 6.500000 0.010000 6.510000 ( 6.520144) memoized: 6.140000 0.000000 6.140000 ( 6.153518)Este es el código de
memoize
:
[~/TheRubyProgrammingLanguage/Chapter6MethodsProcsLambdasAndClosures]$ cat functional_memoize.rb require './functional_partial' require 'benchmark' include Benchmark module Functional # # Return a new lambda that caches the results of this function and # only calls the function when new arguments are supplied. # def memoize cache = {} # An empty cache. The lambda captures this in its closure. lambda {|*args| # notice that the hash key is the entire array of arguments! cache[args] = self[*args] unless cache.has_key?(args) cache[args] } end alias +@ memoize # cached_f = +f end
(caption = "", label_width = nil, format = nil, *labels)
Benchmark::Report
object, which may be
used to collect and report on the results of individual benchmark
tests.
label_width
leading spaces for labels on each line.
caption
at the top of the report, and uses format to format
each line.
Casiano Rodriguez León 2015-01-07