Activate your free membership today | Log-in

Tuesday, May 5th, 2009

A Better Javascript Memoizer

Category: JavaScript, Performance

<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:

JAVASCRIPT:
  1.  
  2. // memoize: a general-purpose function to enable a function to use memoization
  3. //   func: the function to be memoized
  4. //   context: the context for the memoized function to execute within
  5. //   Note: the function must use explicit, string-serializable parameters
  6. function memoize (func, context) {
  7.     function memoizeArg (argPos) {
  8.         var cache = {};
  9.         return function () {
  10.             if (argPos == 0) {
  11.                 if (!(arguments[argPos] in cache)) {
  12.                     cache[arguments[argPos]] = func.apply(context, arguments);
  13.                 }
  14.                 return cache[arguments[argPos]];
  15.             }
  16.             else {
  17.                 if (!(arguments[argPos] in cache)) {
  18.                     cache[arguments[argPos]] = memoizeArg(argPos - 1);
  19.                 }
  20.                 return cache[arguments[argPos]].apply(this, arguments);
  21.             }
  22.         }
  23.     }
  24.     // JScript doesn't grok the arity property, but uses length instead
  25.     var arity = func.arity || func.length;
  26.     return memoizeArg(arity - 1);
  27. }
  28.  

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:

  • Using Terracotta DSO
    Terracotta DSO is an open source technology created by Terracotta, meant to provide clustering to Java at the virtual machine level. It does so by...
  • Microsoft works on Ajax JavaScript tools
    In a session at the recent Ajax Experience conference in San Francisco, Matt Gibbs, development manager in the UI Framework and Services team at...
  • Chapter 22: JavaScript security
    JavaScript continues to find adherents. But this scripting language can be used by malicious hacks to eat up memory .. and worse. Learn about Java...
  • Caching Scenarios
    Caching is a quick and easy way to save roundtrips between your application and where you store your data. However, it’s not as easy as just...
  • FAQ: Lotus Notes, Domino and JavaScript
    Caught in a JavaScript jam? Before posing a question to our SearchDomino.com experts, check out our list of frequently asked questions on JavaScript...

Posted by Dion Almaer at 5:16 am
4 Comments

++++-
4.1 rating from 30 votes

4 Comments »

Comments feed TrackBack URI

Wondering why he used func.arity || func.length instead of just func.length. Mozilla Developer Center marks Function.arity as deprecated.
Nitpicking anyway.

Comment by igstan — May 5, 2009

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.

Comment by philogb — May 5, 2009

I think that ‘Java programmers will think more highly of you’ is more of a negative than a positive :)

Comment by Sembiance — May 5, 2009

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).

Comment by unscriptable — May 5, 2009

Leave a comment

You must be logged in to post a comment.