Wednesday, March 4, 2009

Closures VS. Properties / arguments.callee is expensive

I did some quick benchmarking to test whether it makes a difference to substitute a closure with a function that has a property (sometimes called inside-out-objects). Both are basically the same thing, only that the function property is mutable from the outside while access to the bound lexical variables of the closure is private to the closure.

Here is the source for two simple "getter-makers" that use the different strategies:
var makeGetterProperty = function (name) {
var func = function () {
return this[arguments.callee.__prop_name__]
}
func.__prop_name__ = name;
return func
}

var makeGetterClosure = function (name) {
return function () {
return this[name]
}
}
I timed both execution time of the "make" functions and of the actual getters. Making the getters is almost equally fast in both version; however executing the actual getters differs by a rate of about 150. The closure variant is significantly faster. (All these numbers are only worth their money in FF3.0.x on OSX). Interestingly turning the property variant into a closure that references itself to access the name of the property makes them both almost equally fast.

Conclusion: If you need to build inside-out-objects without closures (e.g. because you need to serialize the function state) that use self-referencing functions instead of accessing arguments.callee.
Post a Comment