for(;;;) vs forEach vs $.each

JavaScript performance comparison

Test case created

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.

Testing in unknown unknown
Test Ops/sec
for(;;;)
var ii = 0, len = arr.length;

for (ii = 0; ii < len; ii += 1) {
  ii / 2;
}
pending…
native forEach
arr.forEach(function (i) {
  i / 2;
});
pending…
$.each
$.each(arr, function (i) {
  i / 2;
});
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:

4 comments

Allen Wirfs-Brock commented :

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)

Todd Anglin commented :

@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.

Allen Wirfs-Brock commented :

@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

Allen Wirfs-Brock commented :

I did a version that includes a pure JS forEach

http://jsperf.com/for-vs-foreach-vs-each/6

Add a comment