Function call overhead (v6)

Revision 6 of this benchmark created by Ger Hobbelt on


Description

Test function call overhead for classical functions, member functions and recursive functions.

Preparation HTML

<script>
  var test1 = [], test2 = [], test3 = [], test,
      limit = 100000,
      MAX_CALL_DEPTH = 100 - 1;

  for (var i = 0; i < limit; i++) {
    test1.push((i * 33.3333 + 3.14152729) % 256);
    test2[i] = NaN;
    test3[i] = Infinity;
  }


  test = test1;


  function fun(num) {
    return test[num];
  }

  function fun2(dst, src, idx) {
    return dst + src;
  }

  function fun3(i, depth) {
    if (depth === MAX_CALL_DEPTH) {
      return test[i];
    } else {
      return test[i] + fun3(i + 1, depth + 1);
    }
  }

  function fun4(i, cps) {
    return function (value) {
      cps(test[i] + value);
    };
  }

  var o;
  o = {
    fun: fun,
    fun2: fun2,
    fun3: function fun3(i, depth) {
      if (depth === MAX_CALL_DEPTH) {
        return test[i];
      } else {
        return test[i] + o.fun3(i + 1, depth + 1);
      }
    },
    fun5: function fun5(v, i, depth, cps) {
      if (depth === MAX_CALL_DEPTH) {
        cps(v + test[i]);
      } else {
        o.fun5(v + test[i], i + 1, depth + 1, cps);
      }
    },
  };
</script>

Setup

var test2 = 0;

Teardown


    console.log('test2 = ', test2);
  

Test runner

Ready to run.

Testing in
TestOps/sec
control
//var test2 = 0;
var local = test;

for (var i = 0, n = test.length; i < n; i++) {
  test2 += test[i];
}
ready
Looped function calls
//var test2 = 0;
var local = test;

for (var i = 0, n = test.length; i < n; i++) {
  test2 += fun(i);
}
 
ready
Looped function calls with caching
//var test2 = 0;
var testFunc = fun;
var local = test;

for (var i = 0, n = test.length; i < n; i++) {
  test2 += testFunc(i);
}
ready
Looped function calls using call
//var test2 = 0;
var local = test;

for (var i = 0, n = test.length; i < n; i++) {
  test2 += fun.call(local, i);
}
 
ready
looped function calls using member
//var test2 = 0;
var local = test;

for (var i = 0, n = test.length; i < n; i++) {
  test2 += o.fun(i);
}
 
ready
Looped function without closure use
//var test2 = 0;
var local = test;

for (var i = 0, n = test.length; i < n; i++) {
  test2 = fun2(test2, test[i], i);
}
 
ready
Recursive function
//var test2 = 0;
var local = test;

for (var i = 0, n = test.length; i < n; i += MAX_CALL_DEPTH + 1) {
  test2 += fun3(i, 0);
}
 
ready
Recursive function method
//var test2 = 0;
var local = test;

for (var i = 0, n = test.length; i < n; i += MAX_CALL_DEPTH + 1) {
  test2 += o.fun3(i, 0);
}
 
ready
Flattened recursion via queue
//var test2 = 0;
var local = test;
var trampoline = [];

for (var i = 0, n = test.length; i < n; i++) {
  trampoline.push(fun4(i, function setTest2(value) {
    test2 = value;
  }));
}

for (var i = 0, n = trampoline.length; i < n; i++) {
  trampoline[i](test2);
}
 
ready
Looped function without closure access
//var test2 = 0;
var testvalue = test2;
var local = test;
var testFun = function (v, i, a) {
  return v + a[i];
}

for (var i = 0, n = local.length; i < n; i++) {
  testvalue = testFun(testvalue, i, local);
}

test2 = testvalue;
 
ready
Function with CPS
//var test2 = 0;
var local = test;
var cps = function ( value ) {
  test2 = value;
};
cps.arr = local;

for (var i = 0, n = test.length; i < n; i += MAX_CALL_DEPTH + 1) {
  o.fun5(test2, i, 0, cps);
}
 
ready

Revisions

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