/**
 * Test foreach loops by 10KK interations: 
 *
 * Chrome 30.0.1599.101
 * f1: 7775 ms
 * f2: 22541 ms
 * f3: 20917 ms
 *
 * Node v0.10.17
 * f1: 8440 ms
 * f2: 14390 ms
 * f3: 19012 ms
 */
 
 
var obj = {
  a: 'a',
  b: 'b',
  c: 'a',
  d: 'd',
  e: 'e',
  f: 'f',
  g: 'g',
  h: 'h',
  i: 'i',
  j: 'j',
  k: 'k',
  l: 'l',
  m: 'm',
  n: 'n',
  o: 'o',
  p: 'p',
  r: 'r',
  s: 's',
  t: 't',
}
 
function count(f, name, q){
    console.time(name)
    while(q--){
        f();
    }
    var t2 = +new Date();
    console.timeEnd(name)
}
function f1( x ){
  /**
   * Returns an array of a given object's own enumerable properties, in the same order as that provided by a for-in loop 
   * (the difference being that a for-in loop enumerates properties in the prototype chain as well).
   */
  var keys = Object.keys(obj); 
  var c = keys.length;

  while (c--) {
    obj[keys[c]];
  }
}

function f2( x ){
  /* classical for-in */
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) obj[key];
  };
}
 
function f3( x ){
  /* modern forEach */
  Object.keys(obj).forEach(function(item) {
    obj[item];
  });
}
 
count(f1, 'f1', 10*1000000); // f1: 7775 ms
count(f2, 'f2', 10*1000000); // f2: 22541 ms
count(f3, 'f3', 10*1000000); // f3: 20917 ms