<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>unscriptable.com &#187; memoization javascript</title>
	<atom:link href="http://unscriptable.com/tag/memoization-javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://unscriptable.com</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Mon, 26 Mar 2012 01:47:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>A Better Javascript Memoizer</title>
		<link>http://unscriptable.com/2009/05/01/a-better-javascript-memoizer/</link>
		<comments>http://unscriptable.com/2009/05/01/a-better-javascript-memoizer/#comments</comments>
		<pubDate>Sat, 02 May 2009 04:08:29 +0000</pubDate>
		<dc:creator>John Hann</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[memoization javascript]]></category>

		<guid isPermaLink="false">http://unscriptable.com/?p=272</guid>
		<description><![CDATA[... what struck me was his use of the function instance to cache the results.  In Javascript, functions are first-class objects and can be assigned properties just like any other object.  But should we do this?  It certainly seems like this could cause intractable problems if used widely.  Imagine if everybody started decorating functions and methods with properties?  ... The two-parameter case is quite ugly and unwieldy, in my opinion.  However, it shed some light on a general-purpose solution, a "memoizer" I'd like to call it.  With a little bit of work, I was able to devise a memoizer for any function with explicitly-declared parameters.  Here it is ...]]></description>
			<content:encoded><![CDATA[<p>Last month, I had the pleasure of meeting tons of excellent and intelligent front-end engineers at JSConf 2009 — the conference for Javascript in Washington DC.  If you are a front-end engineer — or even if you write programs in Javascript for back ends, mobile devices, or desktops — you absolutely have to go to JSConf 2010.  It&#8217;s apparent that Javascript is quickly becoming one of the hottest languages for all environments and applications, and JSConf is the first (and only) conference that deals with Javascript exclusively.</p>
<p><a href="http://jsconf2009.com/">JSConf 2009</a></p>
<p><a href="http://www.slideshare.net/tag/jsconf">Track A presentations from JSConf 2009</a></p>
<p>One of the Track A speakers was Stoyan Stefanov, a really smart guy from Yahoo.   His presentation was about high-performance web apps, but on one slide in particular, I was struck by his implementation of memoization (slide 79 of 87) because he used the function instance to cache the results of the function itself.</p>
<p>If you&#8217;re not familiar with memoization, here&#8217;s a great overview:</p>
<blockquote><p>In computing, memoization is an optimization technique used primarily to speed up computer programs by having function calls avoid repeating the calculation of results for previously-processed inputs.</p></blockquote>
<p><a href="http://en.wikipedia.org/wiki/Memoization">Memoization (Wikipeida)</a></p>
<p>In other words, it&#8217;s a way to cache the results of function calls so that repeated expensive computations or lengthy lookups can be avoided.</p>
<p>Here&#8217;s Stoyan&#8217;s example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> myFunc<span style="color: #009900;">&#40;</span>param<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>myFunc.<span style="color: #660066;">cache</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        myFunc.<span style="color: #660066;">cache</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>myFunc.<span style="color: #660066;">cache</span><span style="color: #009900;">&#91;</span>param<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> result <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ...</span>
        myFunc.<span style="color: #660066;">cache</span><span style="color: #009900;">&#91;</span>param<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> result<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> myFunc.<span style="color: #660066;">cache</span><span style="color: #009900;">&#91;</span>param<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>(Use your imagination to fill in some complex or lengthy task in place of the line with the &#8220;…&#8221;!)</p>
<p>Again, what struck me was his use of the function instance to cache the results.  In Javascript, functions are first-class objects and can be assigned properties just like any other object.  But should we do this?  It certainly seems like this could cause intractable problems if used widely.  Imagine if everybody started decorating functions and methods with properties?  (Actually, debuggers such as Drosera and Firebug now use properties on function instances to help identify them in logs and traces.  It seems to me we should try not to invade on that space!)</p>
<p>So, of course, I set out to answer the question, &#8220;Do we really need to use the function instance to hold the result cache?&#8221;</p>
<p>The answer is &#8220;No&#8221;.  It&#8217;s really quite easy to avoid, too.<br />
<span id="more-272"></span></p>
<p>Keep reading if you&#8217;re interested in the steps I took to come to a general purpose solution.  Otherwise, <a href="#gen_sol">click here</a> to go straight to it.</p>
<h2>A simple example</h2>
<p>Here&#8217;s the simplest form: a constant-valued function with one parameter.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// constant-valued function. not very interesting</span>
<span style="color: #003366; font-weight: bold;">var</span> memoizedFunc0 <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> result<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #006600; font-style: italic;">// in a real-world example this next line would do some</span>
            <span style="color: #006600; font-style: italic;">// complex math instead of just returning a date object</span>
            <span style="color: #000066; font-weight: bold;">return</span> result <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>result <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Notice that we use an auto-execute, anonymous function (the outer function) solely to create a closure around the <code>result</code> variable.  Also notice that the variable, <code>memoizedFunc0</code>, is assigned a reference to the inner anonymous function because the outer function executes immediately and returns it.  The inner function is the one that gets executed when <code>memoizedFunc0</code> is called later in our program.</p>
<p>The memoization happens in the inner function&#8217;s <code>return</code> statement.  We&#8217;re using the short-circuit Boolean OR operator (<code>||</code>) to return <code>result</code> if it is assigned.  Of course, during the first execution, the second half of the statement runs (<code>(result = new Date())</code>), assigning a value to <code>result</code>.</p>
<p>Admittedly, this is a very boring example.  Stoyan&#8217;s was much more interesting since the memoized function took a parameter and returned a different result for each possible parameter.  So let&#8217;s take a look at a multi-valued memoized function:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// multi-valued function with string-serializable param</span>
<span style="color: #003366; font-weight: bold;">var</span> memoizedFunc1 <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> cache <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>param1<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">return</span> param1 <span style="color: #000066; font-weight: bold;">in</span> cache <span style="color: #339933;">?</span> cache<span style="color: #009900;">&#91;</span>param1<span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>cache<span style="color: #009900;">&#91;</span>param1<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>param1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This is similar, but we use a native Javascript object to cache function results.  As long as the parameter, <code>param1</code>, is primitive<a href="#update_2 ">*</a> (or is serializable to a unique string), this will work great.  Property names must be serialized to strings.  Objects that do not have a <code>toString()</code> method to generate a unique string will generally not work.  In most situations, though, you&#8217;ll have an id or key that you can use, anyway.</p>
<p>The inner function simply checks if it already has a value cached and returns it.  Otherwise, it generates a value, caches it, and returns it.</p>
<p><strong>Success! </strong> A memoized function that does not pollute the function instance (and doesn&#8217;t use global variables like some other implementations I&#8217;ve seen).</p>
<h2>A more interesting case: two parameters</h2>
<p>But let&#8217;s not stop there.  What if we have two parameters?  I guess we could generate some sort of string key out of the parameters and use the single-parameter memoized function.  But why?  Generating a unique hash code is expensive and bulky.  Let&#8217;s try to build a 2-parameter memoized function without that.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// multi-valued function with two params</span>
<span style="color: #006600; font-style: italic;">// this time we use two levels of closures and two cache objects</span>
<span style="color: #003366; font-weight: bold;">var</span> memoizedFunc2 <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> cache1 <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>param1<span style="color: #339933;">,</span> param2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>param1 <span style="color: #000066; font-weight: bold;">in</span> cache1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                cache1<span style="color: #009900;">&#91;</span>param1<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #003366; font-weight: bold;">var</span> cache2 <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>param2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">return</span> param2 <span style="color: #000066; font-weight: bold;">in</span> cache2 <span style="color: #339933;">?</span> cache2<span style="color: #009900;">&#91;</span>param2<span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>cache2<span style="color: #009900;">&#91;</span>param2<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>param1<span style="color: #339933;">,</span> param2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
            <span style="color: #000066; font-weight: bold;">return</span> cache1<span style="color: #009900;">&#91;</span>param1<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span>param2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Heh.  The solution is to build two levels of closures!  The first level creates and caches the second level as needed!  The first-level cache ends up holding a reference to an inner anonymous function for each unique <code>param2</code> (and each inner function has it&#8217;s own unique closure).</p>
<h2 id="gen_sol">A general purpose &#8220;memoizer&#8221;</h2>
<p>The two-parameter case is quite ugly and unwieldy, in my opinion.  However, it shed some light on a general-purpose solution, a &#8220;memoizer&#8221; I&#8217;d like to call it.  With a little bit of work, I was able to devise a memoizer for any function with explicitly-declared parameters.  Here it is:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// memoize: a general-purpose function to enable a function to use memoization</span>
<span style="color: #006600; font-style: italic;">//   func: the function to be memoized</span>
<span style="color: #006600; font-style: italic;">//   context: the context for the memoized function to execute within</span>
<span style="color: #006600; font-style: italic;">//   Note: the function must use explicit, primitive parameters (or objects</span>
<span style="color: #006600; font-style: italic;">//     that generate unique strings in a toString() method)</span>
<span style="color: #003366; font-weight: bold;">function</span> memoize <span style="color: #009900;">&#40;</span>func<span style="color: #339933;">,</span> context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">function</span> memoizeArg <span style="color: #009900;">&#40;</span>argPos<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> cache <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>argPos <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #009900;">&#91;</span>argPos<span style="color: #009900;">&#93;</span> <span style="color: #000066; font-weight: bold;">in</span> cache<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    cache<span style="color: #009900;">&#91;</span>arguments<span style="color: #009900;">&#91;</span>argPos<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> func.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>context<span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000066; font-weight: bold;">return</span> cache<span style="color: #009900;">&#91;</span>arguments<span style="color: #009900;">&#91;</span>argPos<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #009900;">&#91;</span>argPos<span style="color: #009900;">&#93;</span> <span style="color: #000066; font-weight: bold;">in</span> cache<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    cache<span style="color: #009900;">&#91;</span>arguments<span style="color: #009900;">&#91;</span>argPos<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> memoizeArg<span style="color: #009900;">&#40;</span>argPos <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000066; font-weight: bold;">return</span> cache<span style="color: #009900;">&#91;</span>arguments<span style="color: #009900;">&#91;</span>argPos<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #006600; font-style: italic;">// JScript doesn't grok the arity property, but uses length instead</span>
    <span style="color: #003366; font-weight: bold;">var</span> arity <span style="color: #339933;">=</span> func.<span style="color: #660066;">arity</span> <span style="color: #339933;">||</span> func.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> memoizeArg<span style="color: #009900;">&#40;</span>arity <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This still might look a little crazy, but it&#8217;s really quite simple.  To satisfy an infinite number of parameters, we simply use recursion.  Every time we recurse, we create another closure.  This just happens in Javascript.  It&#8217;s a natural side-effect of recursion in the language.  All we have to do is use the closures to cache our results.</p>
<p>Our <code>memoize</code> function takes two arguments.  The first is a reference to the function we want to memoize.  The second is the context the memoized function should run in.  For instance, if we want to memoize an object method, we would pass the method in as the first parameter and the object itself as the second parameter.</p>
<p>When the <code>memoize</code> function executes, it first discerns how many formal (explicit) parameters the function has.  Javascript uses the <code>arity</code> property for this purpose.  Of course, no interesting Javascript project would be complete without a Microsoft caveat of some sort.  For some idiotic reason, JScript uses the <code>length</code> property instead of <code>arity</code>.  Other Javascript engines followed suit and deprecated the <code>arity</code> property in favor of the <code>length</code> property.</p>
<p>Next, <code>memoize</code> calls its inner function <code>memoizer</code> on the last parameter.  <code>memoizer</code> constructs a local cache and returns an inner function that either executes and caches our original function if we&#8217;re at the first parameter — or else it caches and executes a call to <code>memoizer</code> with the previous parameter <code>(argPos - 1)</code>.  Each time the function, <code>memoizer</code>, is recursively called it creates a closure around its own <code>cache</code> variable.</p>
<p>Notice that we&#8217;re using the <code>apply</code> method when we finally call our original function.  This allows us to bind to our original context.  We&#8217;re also using <code>apply</code> when we recursively call <code>memoizer</code>.  This allows us to pass the arguments through without knowing how many arguments there are.  The <code>this</code> passed into these calls is arbitrary and could easily have been anything else, including <code>null</code>.</p>
<p>I don&#8217;t know why I chose to start at the last parameter and go backwards.  This routine could go in either direction.  I also have no idea whether this memoizer is any faster or leaner than Stoyan&#8217;s.  I imagine it doesn&#8217;t matter when you consider that both should be much, much faster than the lengthy XHR call or computationally intensive calculation they are meant to prevent.</p>
<h2>OK.  Cool.  But &#8230; um &#8230; why?</h2>
<p>Yes, memoization is a neat concept.  But why use it rather than just hand-coded caching mechanisms?  It&#8217;s easy enough to write a caching routine, right?  Here are a few good reasons:</p>
<ul>
<li>hand-coded caching mechanisms obfuscate your code</li>
<li>multi-variate caching routines are bulky in Javascript</li>
<li>fewer lines of code means fewer bugs</li>
<li>Java programmers will think more highly of you*</li>
</ul>
<p>*Javascript kicks a$$.  Show those stodgy back-end guys what we&#8217;re capable of!</p>
<h2>Let&#8217;s try it out</h2>
<p>So, let&#8217;s test it.  First, let&#8217;s create a sample object to work with.  This object has an &#8220;expensive&#8221; method that uses an XHR request to fetch server-side resources.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// myObj constructor</span>
<span style="color: #003366; font-weight: bold;">function</span> myObj <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
myObj.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    expensiveAjaxLookup<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>y<span style="color: #339933;">,</span> mo<span style="color: #339933;">,</span> d<span style="color: #339933;">,</span> h<span style="color: #339933;">,</span> mn<span style="color: #339933;">,</span> s<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// OK.  No XHR.  Just pretend it does something on the server!</span>
        <span style="color: #006600; font-style: italic;">// Instead we're just going to construct a date string.  Lame, I know.</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prop</span> <span style="color: #339933;">+</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>y <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> mo <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> d <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> h <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> mn <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> s <span style="color: #339933;">||</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// a public property to prove that &quot;this&quot; is really &quot;this&quot; in our memoized methods</span>
    prop<span style="color: #339933;">:</span> <span style="color: #3366CC;">'my date: '</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In order to prove that our memoized methods didn&#8217;t mangle the context of the original method, I added a public property and used it in the <code>expensiveAjaxLookup</code> method.  If our memoized methods lost their context, then this property would be undefined.</p>
<p>Tests:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> o <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> myObj<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
o.<span style="color: #660066;">memoizedLookup</span> <span style="color: #339933;">=</span> memoize<span style="color: #009900;">&#40;</span>o.<span style="color: #660066;">expensiveAjaxLookup</span><span style="color: #339933;">,</span> o<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Note: 8 == September, not August in Javascript</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>o.<span style="color: #660066;">memoizedLookup</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2009</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">17</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>o.<span style="color: #660066;">memoizedLookup</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2009</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">16</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>o.<span style="color: #660066;">memoizedLookup</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2009</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">16</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>o.<span style="color: #660066;">memoizedLookup</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2009</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">16</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>o.<span style="color: #660066;">memoizedLookup</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2009</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">21</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">13</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">26</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">17</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>o.<span style="color: #660066;">memoizedLookup</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2009</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">21</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">13</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">26</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">17</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Output:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">my date: Thu Sep 17 2009 00:00:00 GMT-0400 (EDT)
my date: Wed Sep 16 2009 00:00:00 GMT-0400 (EDT)
my date: Fri Oct 16 2009 00:00:00 GMT-0400 (EDT)
***** cache hit!
my date: Wed Sep 16 2009 00:00:00 GMT-0400 (EDT)
my date: Mon Sep 21 2009 13:26:17 GMT-0400 (EDT)
***** cache hit!
my date: Mon Sep 21 2009 13:26:17 GMT-0400 (EDT)</pre></div></div>

<p>As you can see, the context was correctly bound.  Otherwise, we&#8217;d see &#8221; <code>undefinedThu Sep 17 2009 00:00:00 GMT-0400 (EDT)</code>&#8220;.  The lines that say &#8220;<code>***** cache hit!</code>&#8221; are some debugging statements I threw in.  I sprinkled some console.log() calls all over the memoize function to ensure that the caches were being used as expected.  They are, of course.  I&#8217;ll leave it as an exercise for you to study the behavior of the function, if you are so inclined.  I found the output very interesting and revealing.  Go ahead.  Have fun with it!</p>
<p><strong><em>So, what uses can you conceive for memoization in web apps?  Is it only good for caching XHR requests or summing Fibonacci series?  Please leave a comment or let me know on Twitter!</em></strong></p>
<hr /><strong>[Update]</strong> I just came across two interesting Javascript memoization articles.  In one, the author included an &#8220;unmemoize&#8221; function.  In the other, the &#8220;unmemoification&#8221; happened automatically at a specified time delay.  In the first implementation, though, the function instances are used to hold the unmemoize method.  In the second, a hash key is generated to handle multiple parameters.</p>
<p>It&#8217;s certainly possible to add both features without either of those sacrifices.  I have some ideas how it could be done.  <strong><em>Do you have an implementation that works?  If so, please leave a comment!</em></strong></p>
<p><a href="http://talideon.com/weblog/2005/07/javascript-memoization.cfm">Memoization in JavaScript</a></p>
<p><a href="http://blog.stevenlevithan.com/archives/timed-memoization">Timed Memoization</a></p>
<p>In this article, memoization is used to speed up Bezier curve calculations: <a href="http://osteele.com/archives/2006/04/javascript-memoization">One-Line JavaScript Memoization</a></p>
<hr /><strong id="update_2">[Update 2]</strong>I updated the post to remove references to the word &#8220;serializable&#8221; since I really meant primitives.  In Javascript, all objects are serializable.  However, I really meant <em>uniquely serializable</em>.  All primitives in Javascript are uniquely serializable (<code>String(37)</code> will always be &#8220;37&#8243;).  Objects, Functions, and Arrays are not always unique when serialized.  In most engines, objects, for instance, serialize as &#8220;[Object object]&#8220;.  Dates, despite not being primitive, do have unique serializations (but are locale-dependent).</p>
<p>I also updated the text to clarify that the <code>arity</code> property has been deprecated in favor of the <code>length</code> property.  </p>
]]></content:encoded>
			<wfw:commentRss>http://unscriptable.com/2009/05/01/a-better-javascript-memoizer/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>

