each2 vs each vs quickEach (v24)

Revision 24 of this benchmark created on


Description

Ben Alman says - "Basically, if you're going to do $(this) inside an .each loop, you should consider using the jQuery each2 plugin instead, because it's specifically optimized for this extremely common use case!"

But this implementation has very dangerous impact whenever you'll need to perform nested iterations on jQuery collections - you would no way got a pointer to the outer element from the inner loop, since it gets rewritten by your inner element. This could face you up to data loss (which I had, unfortunately).

I've noticed that to Striker21, who made modified quickEach, which is safe, and perform same.

See it in action.

Preparation HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
(function($) {
  
  // Create a placeholder jQuery object with a length of 1. The single item
  // is completely arbitrary and will be replaced.
  var jq = $([1]);
  
  $.fn.each2 = function( fn ) {
    var i = -1;
    
    while (
      // Set both the first element AND context property of the placeholder
      // jQuery object to the DOM element. When i has been incremented past the
      // end, this[++i] will return undefined and abort the while loop.
      ( jq.context = jq[0] = this[++i] )
      
      // Invoke the callback function in the context of the DOM element,
      // passing both the index and the placeholder jQuery object in. Like
      // .each, if the callback returns `false`, abort the while loop.
      && fn.call( jq[0], i, jq ) !== false
    ) {}
    
    // Return the initial jQuery object for chainability.
    return this;
  };
  
})(jQuery);
(function($)
{
        $.fn.quickEach = function(c)
        {
                var j = $([0]), i = -1, l = this.length;
                while(
                        ++i < l
                        && (j[0] = this[i])
                        && c.call(j, i, j[0]) !== false
                );
                return this;
        };
})(jQuery);  
// Create a whole bunch of elements for iteration.
  var elems = $('<div/>').append(Array(1000).join('<span/>')).children();
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
jQuery each2 plugin
elems.each2(function(i, jq) {
 jq;   // jQuery object
 this; // DOM element
});
ready
jQuery core .each method
elems.each(function(i, elem) {
 $(this); // jQuery object
 this;    // DOM element
});
ready
jQuery quickEach plugin
elems.quickEach(function(i, elem) {
 this; // jQuery object
 elem; // DOM element
});
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.