So here is my simple little Fibonacci program.
var fib = function(x) {
if (x === 0) return 0;
if (x === 1) return 1;
return fib(x-1) + fib(x-2)
}
Nice and simple. Now I create a memoization handler. This handler implements the memoization logic as part of a Proxy handler.
var memoizerMaker = function() {
this.memoStore = {};
}
memoizerMaker.prototype.apply = function (target, thisValue, args) {
var argsKey = args.toString();
if (this.memoStore[argsKey] !== undefined) {
return this.memoStore[argsKey];
} else {
let value = target.apply(thisValue,args);
this.memoStore[argsKey] = value;
return value;
}
So this object has a "memo store" where it stores solutions. It also has a apply function that will be used by the Proxy. This apply function will be called instead of the target function. This apply will then call the target function and store the output.
Now to make my Fibonacci function use this memoization object.
fib = new Proxy(fib, new memoizerMaker());
Now let's say I am trying to compute the length of a Collatz sequence. It goes like this:
function computeCollatzLength(number) {
if (number === 1) {
return 1;
} else if (number % 2 === 0) {
return 1 + computeCollatzLength(number / 2);
} else {
return 1 + computeCollatzLength(number * 3 + 1);
}
}
Now memoizing this isn't as useful as memoizing Fibonacci. But imagine that you call this function multiple times. The function (actually the Proxy) has an attached object that stores all the values. All you have to do is this:
computeCollatzLength = new Proxy(
computeCollatzLength,
new memoizerMaker());
This is some very elegant stuff!
This comment has been removed by a blog administrator.
ReplyDelete