I created a withMemo
function that returns a memoized version of the provided function.
JavaScript
x
2
1
const memoizedFn = withMemo(fn)
2
How can I memoize this fibonacci function that works with recursion ?
JavaScript
1
7
1
const fibo = (n) => {
2
3
if (n <= 1) return 1
4
5
return fibo(n - 2) + fibo(n - 1)
6
}
7
Indeed withMemo(fibo)
doesn’t improve performance since the recursive calls inside fibo
still point to the unmemoized version…
So I have to alter the declaration of fibo to make momoization work:
JavaScript
1
12
12
1
const momoizableFibo = memoizer => {
2
const fibo = (n) => {
3
4
if (n <= 1) return 1
5
6
return memoizer(fibo)(n - 2) + memoizer(fibo)(n - 1)
7
}
8
9
return memoizer(fibo)
10
}
11
// momoizableFibo(withMemo)(50) // takes a ms
12
Is there a way to memoize fibo
(or any other recursive function for that matter) without altering it’s declaration in the way I did ?
Advertisement
Answer
You can use let fibo
instead of const fibo
. Then replace the fibo
variable with a memoized version. By updating fibo
the nested call will now refer to the memoized fibo
function instead of the original.
JavaScript
1
24
24
1
let fibo = (n) => {
2
console.log(n); // <- show original fibo calls
3
if (n <= 1) return 1;
4
return fibo(n - 2) + fibo(n - 1);
5
}
6
// update fibo variable so the nested fibo call calls the memoized version
7
fibo = withMemo(fibo);
8
9
console.log("fibo(3)", "//=>", fibo(3));
10
console.log("fibo(5)", "//=>", fibo(5));
11
console.log("fibo(2)", "//=>", fibo(2));
12
13
14
// simplified memoize function, only works for serializable parameters
15
function withMemo(fn) {
16
const cache = new Map();
17
return function (args) {
18
const key = JSON.stringify(args);
19
if (cache.has(key)) return cache.get(key);
20
const result = fn(args);
21
cache.set(key, result);
22
return result;
23
}
24
}