for(;;;) vs forEach vs $.each
JavaScript performance comparison
Preparation code
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
Benchmark.prototype.setup = function() {
var i;
window.arr = [];
for (i = 0; i < 10000; i += 1) {
arr.push(i);
}
};
</script>
Preparation code output
Test runner
Warning! For accurate results, please disable Firebug before running the tests. (Why?)
Java applet disabled.
| Test | Ops/sec | |
|---|---|---|
for(;;;) |
|
pending… |
native forEach |
|
pending… |
$.each |
|
pending… |
Compare results of other browsers
Revisions
You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:
- Revision 1: published
- Revision 3: published by Todd
- Revision 4: published by Damon Oehlman
- Revision 5: published
- Revision 6: published by Allen Wirfs-Brock
- Revision 8: published by Allen Wirfs-Brock
- Revision 9: published by mike
- Revision 10: published by mike
- Revision 11: published by mike
- Revision 12: published by mike
- Revision 13: published
- Revision 14: published
- Revision 15: published
- Revision 16: published by Arthur Corenzan
- Revision 17: published
- Revision 18: published
- Revision 19: published
- Revision 20: published
- Revision 21: published
- Revision 22: published by pivolan
- Revision 23: published
4 comments
Clearly, there are some fundamental differences between the test cases in that the second two do a function call on each iteration (and actually create a new function each iteration). A more apples-to-applies comparison would code the for(;;) body as:
...{ (function(ii) { ii/2})(i); }
or define and name the function outside of the loops and make the forEach call look like:
arr.forEach(func)
@Allen- Since it is easy to modify and extend tests, I've done just that with your suggested modifications:
http://jsperf.com/for-vs-foreach-vs-each/3
You'll see that manually caching the function used by $.each and forEach has virtually no effect. This is probably due to internal optimizations in modern JS engines. The self-executing function in a for loop is very slow by comparison.
Hope this helps paint the full picture.
@Todd Very interesting. TMost modern engine do seem to be optimizing away the per iteration closure creation. Apparently IE9 is not doing so. It's profile was closer to what I was originally expecting to see.
These result raise another interesting possibility. It looks to me that the engines are optimizing away the closure creation but probably not in-lining and optimizing the actual forEach method. I would expect such in-lining to enable further optimizations that would bring forEach closer to the for(;;) numbers. I believe that some of these engines engines have the ability to do this style of optimization.
I wonder if the fact the Array.prototype.forEach is a built-in functions prevents that form of optimization in this case. An interesting experiment would be to modify the test to use a pure JavaScript forEach implementation such as https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach#Compatibility
I did a version that includes a pure JS forEach
http://jsperf.com/for-vs-foreach-vs-each/6