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

Revision 8 of this benchmark created by Allen Wirfs-Brock on


Description

Added a test case that uses a pure JS version of forEach

Preparation HTML

<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

Setup

var i,
        cachedFunc = function(i){ i / 2; };
    
    window.arr = [];
    
    for (i = 0; i < 10000; i += 1) {
      arr.push(i);
    }
    
    /* pure JS forEach from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach#Compatibility */
    arr.forEachJS = function( callback, thisArg ) {  
      
        var T, k;  
      
        if ( this == null ) {  
          throw new TypeError( " this is null or not defined" );  
        }  
      
        // 1. Let O be the result of calling ToObject passing the |this| value as the argument.  
        var O = Object(this);  
      
        // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".  
        // 3. Let len be ToUint32(lenValue).  
        var len = O.length >>> 0; // Hack to convert O.length to a UInt32  
      
        // 4. If IsCallable(callback) is false, throw a TypeError exception.  
        // See: http://es5.github.com/#x9.11  
        if ( {}.toString.call(callback) != "[object Function]" ) {  
          throw new TypeError( callback + " is not a function" );  
        }  
      
        // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.  
        if ( thisArg ) {  
          T = thisArg;  
        }  
      
        // 6. Let k be 0  
        k = 0;  
      
        // 7. Repeat, while k < len  
        while( k < len ) {  
      
          var kValue;  
      
          // a. Let Pk be ToString(k).  
          //   This is implicit for LHS operands of the in operator  
          // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.  
          //   This step can be combined with c  
          // c. If kPresent is true, then  
          if ( k in O ) {  
      
            // i. Let kValue be the result of calling the Get internal method of O with argument Pk.  
            kValue = O[ k ];  
      
            // ii. Call the Call internal method of callback with T as the this value and  
            // argument list containing kValue, k, and O.  
            callback.call( T, kValue, k, O );  
          }  
          // d. Increase k by 1.  
          k++;  
        }  
        // 8. return undefined  
      };

Test runner

Ready to run.

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

for (ii = 0; ii < len; ii += 1) {
  ii / 2;
}
ready
native forEach
arr.forEach(function (i) {
  i / 2;
});
ready
JS forEach
arr.forEachJS(function (i) {
  i / 2;
});
ready
$.each
$.each(arr, function (i) {
  i / 2;
});
ready
native forEach (cached func
arr.forEach(cachedFunc);
ready
JS forEach (cached func)
arr.forEachJS(cachedFunc);
ready
$.each (cached func)
$.each(arr, cachedFunc);
ready
for(;;;) (self func)
var ii = 0, len = arr.length;

for (ii = 0; ii < len; ii += 1) {
  (function(i){ i / 2; }(ii));
}
ready
reverse for(;;;)
var ii, len = arr.length;

for (ii = len - 1; ii >= 0; ii--) {
  ii / 2;
}
ready
for(;;) with array access
var ii = 0, len = arr.length;

for (ii = 0; ii < len; ii += 1) {
  arr[ii] / 2;
}
ready

Revisions

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