Tuesday, May 5th, 2009
A Better Javascript Memoizer
<p>We have covered memoizers in the past, but John Hann has posted on a nice implementation that takes advantage of closures, arity, and recursion -- 3 concepts/features that Javascript was meant to use.It leads to this generic version:
-
-
// memoize: a general-purpose function to enable a function to use memoization
-
// func: the function to be memoized
-
// context: the context for the memoized function to execute within
-
// Note: the function must use explicit, string-serializable parameters
-
function memoize (func, context) {
-
function memoizeArg (argPos) {
-
var cache = {};
-
return function () {
-
if (argPos == 0) {
-
if (!(arguments[argPos] in cache)) {
-
cache[arguments[argPos]] = func.apply(context, arguments);
-
}
-
return cache[arguments[argPos]];
-
}
-
else {
-
if (!(arguments[argPos] in cache)) {
-
cache[arguments[argPos]] = memoizeArg(argPos - 1);
-
}
-
return cache[arguments[argPos]].apply(this, arguments);
-
}
-
}
-
}
-
// JScript doesn't grok the arity property, but uses length instead
-
var arity = func.arity || func.length;
-
return memoizeArg(arity - 1);
-
}
-
and this conclusion:
Yes, memoization is a neat concept. But why use it rather than just hand-coded caching mechanisms? It’s easy enough to write a caching routine, right? Here are a few good reasons:
- hand-coded caching mechanisms obfuscate your code
- multi-variate caching routines are bulky in Javascript
- fewer lines of code means fewer bugs
- Java programmers will think more highly of you ;)
Related Content:











Wondering why he used func.arity || func.length instead of just func.length. Mozilla Developer Center marks Function.arity as deprecated.
Nitpicking anyway.
I coded a memoization function that works with non-unary functions some time ago (last year actually):
http://blog.thejit.org/2008/09/05/memoization-in-javascript/
I wonder what are the tradeoffs/benefits of using my memoization function and his.
I think that ‘Java programmers will think more highly of you’ is more of a negative than a positive :)
Hey igstan, thanks for alerting me to the fact that arity is deprecated. I have no idea why we’d want to deprecate the proper mathematical term. Go figure! :-)
@philogb: You’ve got a great article. Very in-depth discussion. I think the main difference between our implementations is that I am favoring recursion over serialization of multiple parameters (as yours implements). If I am in total control of the data that will be fed in as parameters, then I might not be so picky about serialization. However, my mind is always focused on componentization and code reuse. (I think it’s always a good idea to program defensively, too.) Therefore, I wanted to find a method that could work with any parameter data. I didn’t quite do it, but I feel I got further than any other implementation I’ve seen so far (in Javascript).