Skip to content

Instantly share code, notes, and snippets.

@thetallweeks
Created August 22, 2014 17:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thetallweeks/a55cc2fedfd65d16b9ea to your computer and use it in GitHub Desktop.
Save thetallweeks/a55cc2fedfd65d16b9ea to your computer and use it in GitHub Desktop.
Memoize functions
http://jsperf.com/another-memoization-comparison
// underscore.js memoize
function memoize1(func) {
"use strict";
var memo = {};
var slice = Array.prototype.slice;
return function() {
var key = "" + slice.call(arguments);
return (key in memo) ? memo[key] : (memo[key] = func.apply(this, arguments));
};
};
fib1 = memoize1(getFibFn());
//memoize.js - by @addyosmani
// with tweaks from @philogb, @mathias, @DmitryBaranovsk, @JamieMason
function memoize2(func) {
"use strict";
var cache = (func.memoize = func.memoize || {}),
stringifyJson = JSON.stringify,
sliceArray = Array.prototype.slice;
return function () {
var hash = stringifyJson(sliceArray.call(arguments));
return (hash in cache) ? cache[hash] : cache[hash] = func.apply(this, arguments);
};
};
fib2 = memoize2(getFibFn());
//memo3 - unscriptables implem.
function memoize3(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);
}
fib3 = memoize3(getFibFn());
//memo4 - by stevenlevithan
function memoize4(functor, expiration) {
var memo = {};
return function () {
var key = Array.prototype.join.call(arguments, "§");
if (key in memo)
return memo[key];
if (expiration)
setTimeout(function () {delete memo[key];}, expiration);
return memo[key] = functor.apply(this, arguments);
};
};
fib4 = memoize4(getFibFn());
//memo5 - @gbradley
function memoize5(fn){
var lookup={};
return function(){
var args=[].slice.call(arguments);
var key=JSON.stringify(args);
var result=lookup[key];
if (!result){
result=fn.apply(this,args);
lookup[key]=result;
}
return result;
};
};
fib5 = memoize5(getFibFn());
//memo6 (fastest) - by @madrobby/thomas fuchs
Function.prototype.cached = function(){
var self = this, cache = {};
return function(arg){
if(arg in cache) {
//console.log('Cache hit for '+arg);
return cache[arg];
} else {
//console.log('Cache miss for '+arg);
return cache[arg] = self(arg);
}
};
};
fib6 = getFibFn().cached();
// memo7 - @medikoo
// https://github.com/medikoo/es5-ext/blob/master/lib/Function/memoize.js
var memoize7 = (function () {
var isArray = Array.isArray
, slice = Array.prototype.slice
, resolve;
resolve = function (args) {
return this.map(
function (r, i) {
return r ? r(args[i]) : args[i];
}).concat(slice.call(args, this.length));
};
return function (fn, length, resolvers) {
var cache, resolver;
cache = [];
if (isArray(length)) {
resolvers = length;
length = fn.length;
} else if (length == null) {
length = fn.length;
}
resolver = resolvers ? resolve.bind(resolvers) : null;
return function () {
var limit, i, index, args, current, found;
args = resolver ? resolver(arguments) : arguments;
i = 0;
index = limit = (length === true) ? args.length : length;
current = cache;
if (limit === 0) {
found = current.hasOwnProperty(0);
} else {
while (i !== limit) {
if (!current[index]) {
current = (current[index] = [
[args[i]],
[]
]);
index = 0;
} else if (
(index = (current = current[index])[0].indexOf(args[i])) === -1) {
index = current[0].push(args[i]) - 1;
found = false;
} else {
found = current[1].hasOwnProperty(index);
}
current = current[1];
++i;
}
}
if (found) {
return current[index];
}
return current[index] = fn.apply(this, args);
};
};
}());
fib7 = memoize7(getFibFn());
//memo8 - by @AutoSponge
(function (GLOBAL, stringifyJson) {
"use strict";
GLOBAL.memoize8 = GLOBAL.memoize8 || stringifyJson && function (func) {
var cache = (func.memoize = func.memoize || {});
return function () {
var hash = stringifyJson(arguments);
return (hash in cache) ? cache[hash] : cache[hash] = func.apply(this, arguments);
};
} || function (func) {
return func;
};
}(this, typeof JSON !== "undefined" && JSON.stringify));
fib8 = this.memoize8(getFibFn());
// Scott Sauyet - http://articles.local/articles/FunctionalMemoizing/
var memoize9 = function memoize(fn) {
var cache = {}, slice = [].slice;
return function() {
var args, arg;
if (arguments.length === 0) {
return (args in cache) ? cache[args] : (cache[args] = fn());
} else {
arg = arguments[0];
args = slice.call(arguments, 1);
return (cache[arg] || (cache[arg] = memoize( function () {
return fn.apply(this, [].concat(arg, slice.call(arguments)));
}))).apply(this, args);
}
}
};
fib9 = memoize9(getFibFn());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment