Skip to content

Instantly share code, notes, and snippets.

@b-studios
Created June 13, 2013 13:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save b-studios/5773521 to your computer and use it in GitHub Desktop.
Save b-studios/5773521 to your computer and use it in GitHub Desktop.
Simple loop compilation
function iterator(f, bindings) {
bindings = bindings || {};
var matches = f.toString().match(/function[^(]*\(\s*(\w+)\s*\)[^{]*(.*)/);
if (!matches) {
console.log("iterator function has wrong format, please use only one argument");
}
var compiled,
k,
funStr = [],
argNames = [],
argValues = [],
argName = matches[1],
body = matches[2];
for(k in bindings) {
if (bindings.hasOwnProperty(k)) {
argNames.push(k);
argValues.push(bindings[k]);
}
}
function freshName(name) {
if (bindings.hasOwnProperty(name))
return freshName("_" + name);
return name;
}
var arrName = freshName("els"),
counterName = freshName("i"),
lengthName = freshName("length");
funStr.push("(function(", argNames.join(','), ")", "{",
"return function(",arrName,") { ",
"var ", counterName ,",",
lengthName, "=", arrName,".length,",
argName, ";",
"for(",counterName,"=0;",counterName,"<",lengthName,";",counterName,"++) {",
argName, "=",arrName,"[",counterName,"];",
body,
"}",
"}",
"})"
)
var compiled = eval.call(this, funStr.join(''));
return compiled.apply(this, argValues);
}
var printAll = iterator(function(el) {
console.log(el);
});
printAll([1,2,3]);
// yields:
// 1
// 2
// 3
// the closed environment has to be specified explicitly
var printClosure = iterator(function(el) {
console.log(el + a);
}, {
a: 5
});
printClosure([1,2,3]);
// yields
// 6
// 7
// 8
@b-studios
Copy link
Author

I didn't perform a representative empirical study, but a quick test (with a list of 100,000 elements) suggests that the compiled version is about 30 times faster then using jQuery's $.each.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment