Thursday, April 5, 2012

Just wrote an auto-memoizer for single-valued functions as an answer to a StackOverflow question:
function memoize(func, max) {
    max = max || 5000;
    return (function() {
        var cache = {};
        var remaining = max;
        function fn(n) {
            return (cache[n] || (remaining-- >0 ? (cache[n]=func(n)) : func(n)));
        }
        return fn;
    }());
}

function fact(n) {
    return n<2 ? 1: n*fact(n-1);
}

var memfact = memoize(fact,170);
Based on an implementation of factorial function by user xPheRe:
var factorial = (function() {
    var cache = {},
        fn = function(n) {
            if (n === 0) {
                return 1;
            } else if (cache[n]) {
                return cache[n];
            }
            return cache[n] = n * fn(n -1);
        };
    return fn;
}());
Things I like:
  • It memoizes anything
  • The cache limit prevents stupid things like memoizing where there are floats
  • It's faster than the if/else original
I could add in a trigger which replaced the function with a straight call after too many misses, so that even wrongly-memoized functions weren't slowed down after a number of calls.