Skip to content

Instantly share code, notes, and snippets.

@anoras
Created September 7, 2010 10:10
Show Gist options
  • Save anoras/568120 to your computer and use it in GitHub Desktop.
Save anoras/568120 to your computer and use it in GitHub Desktop.
Function.prototype.memoize = function() {
var fn=this;
var args = Array.prototype.slice.call(arguments);
var target = args.length > 0 ? args[0] : null;
fn._vals = fn._vals || {};
return function() {
var call_args = Array.prototype.slice.call(arguments);
if (fn._vals[call_args] !== undefined) return fn._vals[call_args];
fn._vals[call_args] = fn.apply(target, arguments);
return fn._vals[call_args];
}
}
// This works because it references fib through a closure.
var fib = (function(n) {
recs++;
if (n<2) {
return n;
} else {
return fib(n-1)+fib(n-2);
}
}).memoize();
for (var i = 0; i < 30; i++) print(fib(i));
// This also works, but it invokes the non-memoized fib because arguments.callee references the non-memoized function. E.g. 4356586 recursions are required to calculate the sequence versus 30 in the memoized version.
var fib = (function(n) {
recs++;
if (n<2) {
return n;
} else {
return arguments.callee(n-1)+arguments.callee(n-2);
}
}).memoize();
for (var i = 0; i < 30; i++) print(fib(i));
Function.prototype.memoize = function() {
var fn;
eval("fn="+this.toString().replace(/arguments.callee/gm,"arguments.callee.caller"));
var args = Array.prototype.slice.call(arguments);
var target = args.length > 0 ? args[0] : null;
fn._vals = fn._vals || {};
return function() {
var call_args = Array.prototype.slice.call(arguments);
if (fn._vals[call_args] !== undefined) return fn._vals[call_args];
fn._vals[call_args] = fn.apply(target, arguments);
return fn._vals[call_args];
}
}
var recs = 0;
var fib = (function(n) {
recs++;
if (n<2) {
return n;
} else {
return arguments.callee(n-1)+arguments.callee(n-2);
}
}).memoize();
for (var i = 0; i < 30; i++) print(fib(i));
print(recs);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment