angularjs invoke apply vs switch (v2)

Revision 2 of this benchmark created on


Preparation HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/mootools/1.3/mootools-yui-compressed.js"></script>

Setup

//
  
  var _fn = [],
    _args = []
    _fn.push(function() {
      return
    })
    _args.push([])
    _fn.push(function(a) {
      return a
    })
    _args.push(['a'])
    _fn.push(function(a, b) {
      return a + b
    })
    _args.push(['a', 'b'])
    _fn.push(function(a, b, c) {
      return a + b + c
    })
    _args.push(['a', 'b', 'c'])
    _fn.push(function(a, b, c, d) {
      return a + b + c + d
    })
    _args.push(['a', 'b', 'c', 'd'])
    _fn.push(function(a, b, c, d, e) {
      return a + b + c + d + e
    })
    _args.push(['a', 'b', 'c', 'd', 'e'])
    _fn.push(function(a, b, c, d, e, f) {
      return a + b + c + d + e + f
    })
    _args.push(['a', 'b', 'c', 'd', 'e', 'f'])
    _fn.push(function(a, b, c, d, e, f, g) {
      return a + b + c + d + e + f + g
    })
    _args.push(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
    _fn.push(function(a, b, c, d, e, f, g, h) {
      return a + b + c + d + e + f + g + h
    })
    _args.push(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
    _fn.push(function(a, b, c, d, e, f, g, h, i) {
      return a + b + c + d + e + f + g + h + i
    })
    _args.push(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
    _fn.push(function(a, b, c, d, e, f, g, h, i, j) {
      return a + b + c + d + e + f + g + h + i + j
    })
    _args.push(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
    _fn.push(function(a, b, c, d, e, f, g, h, i, j, k) {
      return a + b + c + d + e + f + g + h + i + j + k
    })
    _args.push(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'])
  
    var fn, args;
  
  function chooseRandomFn() {
    var num = ~~ (Math.random() * _fn.length);
    fn = _fn[num];
    args = _args[num];
  }
  
  // These fns were generated with code, because I'm lazy. But eval'ed code doesn't get optimized like normal code, so you'll have to run this code somewhere and copy it in place.
  // console.log("var _fn = [], _args = []")
  // for( var i = 0; i <= 11; i++ ){
  //   var args = [];
  //   var vals = [];
  //   for( var argN = 0; argN < i; argN++ ){
  //     var c = String.fromCharCode(97 + argN)
  //     args.push( c )
  //     vals.push( "'" + c + "'" )
  //   }
  //   console.log( "_fn.push( function (" + args.join(',') + "){ return " + args.join('+') + " } )" )
  //   console.log( "_args.push( [" + vals.join(',') + "] )" )
  // }

Test runner

Ready to run.

Testing in
TestOps/sec
switch
chooseRandomFn();

// Performance optimization: http://jsperf.com/apply-vs-call-vs-invoke
switch (self ? -1 : args.length) {
  case 0:
    return fn();
  case 1:
    return fn(args[0]);
  case 2:
    return fn(args[0], args[1]);
  case 3:
    return fn(args[0], args[1], args[2]);
  case 4:
    return fn(args[0], args[1], args[2], args[3]);
  case 5:
    return fn(args[0], args[1], args[2], args[3], args[4]);
  case 6:
    return fn(args[0], args[1], args[2], args[3], args[4], args[5]);
  case 7:
    return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
  case 8:
    return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
  case 9:
    return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
  case 10:
    return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]);
  default:
    return fn.apply(self, args);
}
ready
apply
chooseRandomFn();

return fn.apply(self, args);
ready

Revisions

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