-
Website
http://osteele.com -
Original page
http://osteele.com/archives/2006/04/javascript-memoization -
Subscribe
All Comments -
Community
-
Top Commenters
-
llimllib
1 comment · 2 points
-
sbecker
1 comment · 1 points
-
mattherdy
1 comment · 1 points
-
ultrasaurus
1 comment · 1 points
-
Facebook User
2 comments · 1 points
-
-
Popular Threads
This article taught me a few new words (nullary, memoize) which will come in handy, and a few more of JavaScript's subtleties.
So, memoization. I like it. But I'm just a simple engineer unconcerned with language theory, and more concerned with getting stuff to work good, and stuff. Keith Gaughan's solution -- appending .memoize() -- onto a function certainly seems the least intrusive and tidy. And, agreed, managing multiple files and dependencies on a server is annoying. One solution for that would be to introduce a build-step to the development, resulting in a single file. Yeah... Edit, make, test. It's not the craziest flow in the world, though it is one more darned thing.
Reassigning the function to "return length" is appealing but troubling. It's an opaque state, it's self-modifying code, oh, it troubles me. And even more so for the self-neutralizing "Thing.noFun = function(){};"!
While these strategies are interesting, I'm always concerned that my code may be maintained by cave men, or myself late on a Sunday. These dynamic features are, obviously, a lot of fun... but I must confess: I'll opt for the first naive "Thag not compute Bezier length twice if Thag already have Bezier length! Ha!" solution: function bezierLength() { compute if needed, return }". Easy peasy.
> The inner function captures the variables from the outer function.
makes me a little suspicious of the fancier solutions you present. It's true that the memoization is caught up in the domain logic, but I have needed to do this rarely enough that it hasn't really bothered me. I'm more wary of memory leaks or ineffeciencies in the underlying runtime when using closures than bugs caused by rewriting a little code to test for the presence of a stored value.
Also, here's another take on your memoization routine that uses arguments.callee instead of closures.
function assignMemoizable( object, func , name ){
var f = function (){
if stored value exists
return from cache
else
return arguments.callee.originalFunction.apply( this , arguments );
}
f.originalFunction = func;
object.prototype[ name ] = f;
}
That seems like it would work too, no?
http://www.cs.cityu.edu.hk/~hwchun/31337/blog/2...
This strikes me as something I might actually use in a number of practical cases though. Thanks for going into such detail, great explanations.
Could you please correct shortened memoizeConstantMethod to define local 'value' variable :)
The current version does not work correctly when called more then once for different methods.
Bezier.prototype.getLength = function() {
var length = ... // expensive computation
this.getLength = new Function ("return " + length);
return length;
}