ikemonn's blog

技術ネタをちょこちょこと

【Underscore.js】_.memoizeを読んだ

jashkenas/underscore_.memoizeを読んだ。

概要

_.bind(function, object, *arguments

一度計算した値をキャッシュしておく機能を関数に付け加える。

var num = 40;

var fib = function(n) {
    return n < 2 ? n : fib(n - 1) + fib(n - 2);
};

console.time('not memoize');
console.log(fib(num));
console.timeEnd('not memoize’); // not memoize: 1701.395ms

var fib2 = _.memoize(function(n) {
    return n < 2 ? n : fib2(n - 1) + fib2(n - 2);
});

console.time('memoize');
console.log(fib2(num));
console.timeEnd('memoize’); // memoize: 0.979ms

ソースコード

_.memoize = function(func, hasher) {
    var memoize = function(key) {
      var cache = memoize.cache;
      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
      return cache[address];
    };
    memoize.cache = {};
    return memoize;
  };

hasherが与えられなければ、関数に与えられる引数をkeyにしたキャッシュ用の配列を内部で持っておき、キャッシュにヒットしたらそれを返している。

参考

jashkenas/underscore