Memoize in Clojure
2023-05-17
Memoization is the process of caching expensive calculations so that they can later be used to speed up a program.
An example of this in Clojure can be seen with an implementation of this fib
function, which returns the
nth Fibonacci number.
(defn fib [n]
(cond
(<= n 0) 0
(= n 1) 1
:else (+ (fib (- n 1)) (fib (- n 2)))))
We can see that it simply uses the recursive definition of the nth Fibonacci number. But this is actually pretty slow because the recursion is calculating the same values multiple times.
For example:
(time (fib 40)) ;=>"Elapsed time: 964.588292 msecs"
;=>102334155
A way to optimize this in terms of speed would be to create a memoized version of the fib
function. This will speed it up,
but also take up more memory during runtime.
(def fib-memoize
(memoize
#(cond
(<= % 0) 0
(= % 1) 1
:else (+ (fib-memoize (- % 1)) (fib-memoize (- % 2))))))
Note that we can't just do (def fib-memoize (memoize fib))
because that will only memoize the top
call of fib
and none of the other recursive ones.
This memoization greatly increases the speed of the calculation:
(time (fib-memoize 40)) ;=>"Elapsed time: 0.352458 msecs"
;=>102334155