jQuery.fn.each vs. jQuery.fn.quickEach

JavaScript performance comparison

Revision 59 of this test case created by David Seigle

Info

The quickEach method will pass a non-unique jQuery instance to the callback meaning that there will be no need to instantiate a fresh jQuery instance on each iteration. Most of the slow-down inherent in jQuery’s native iterator method (each) is the constant need to have access to jQuery’s methods, and so most developers see constructing multiple instances as no issue… A better approach would be quickEach.

Added "quickerEach" implementation (slightly modifies the original quickEach code).

Note that the performance is VERY DIFFERENT when the loop actually does something with the jQuery object. When you use "addClass" in the loop then "quickerEach" performs best, when it is not there, the for-loop performs best. It feels like the JS runtimes are able to realise that the for-loop doesn't actually need to do anything - and optimises for that scenario. That's really clever - but it makes measuring performance difficult.

Optimized the for loop.

Preparation code

<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<script>
  var a = $('<div/>').append(Array(100).join('<a></a>')).find('a');

  jQuery.fn.quickEach = (function() {
    var jq = jQuery([1]);
    return function(c) {
      var i = -1,
          el, len = this.length;
      try {
        while (++i < len && (el = jq[0] = this[i]) && c.call(jq, i, el) !== false);
      } catch (e) {
        delete jq[0];
        throw e;
      }
      delete jq[0];
      return this;
    };
  }());

  jQuery.fn.quickerEach = (function() {
    var jq = jQuery([1]);
    return function(c) {
      var i = -1,
          el;
      try {
        while (el = jq[0] = this[++i] && c.call(jq, i, el) !== false);
      } catch (e) {
        jq[0]=1;
        throw e;
      }
      jq[0]=1;
      return this;
    };
  }());
</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
.each()
a.each(function() {
  $(this).addClass("wibble");
});
pending…
.quickEach()
a.quickEach(function() {
  this.addClass("wibble"); // jQuery object
});
pending…
for loop
var jq = jQuery([1]);
for (var i = a.length; i--;) {
  jq[0] = a[i];
  jq.addClass("wibble"); // jQuery object
}
pending…
.quickerEach()
a.quickerEach(function() {
  this.addClass("wibble"); // jQuery object
});
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:

0 comments

Add a comment