Function#bind tests

Benchmark created by John-David Dalton on


Description

Testing various bind implementations of @bga_

Preparation HTML

<script>
  /*
    uses compilation to optimize `Function#bind`, but not real `bind` which in fact - `carry`
    inlines consts.
  */
  
  var defaultThis = (function() {
   return this
  })();
  
  this._fastBind = (function() {
   var _quoteString = function(s) {
    return s.replace(/\n|\r|\\|\"/g, function(c) {
     switch (c) {
     case '\n':
      return '\\n';
     case '\r':
      return '\\r';
     case '\\':
      return '\\\\';
     case '\"':
      return '\\\"';
     }
    });
   };
  
   return function(_fn, that, args) {
    var _ret;
  
    if (args == null) {
     _ret = (that === defaultThis) ?
     function() {
      return (arguments.length > 0) ? _fn.apply(this, arguments) : _fn.call(this)
     } : function() {
      return (arguments.length > 0) ? _fn.apply(that, arguments) : _fn.call(that)
     };
    }
    else {
     var argsStr = '_fn,',
         callStr = '',
         nonConstArgs = [_fn],
         j = 1;
  
     if (that !== defaultThis) {
      callStr = '.call(that,';
      argsStr += 'that,';
      nonConstArgs[j++] = that;
     }
     else {
      callStr = '(';
     }
  
     var i = -1;
     while (++i < args.length) {
      var a = args[i];
  
      if (a === null) {
       callStr += 'null,';
      }
      else {
       switch (typeof(a)) {
       case 'string':
        callStr += '"' + _quoteString(a) + '",';
        break;
       case 'number':
       case 'boolean':
       case 'undefined':
        callStr += '' + a + ',';
        break;
       default:
        callStr += 'a' + i + ',';
        nonConstArgs[j++] = a[i];
        argsStr += 'a' + i + ','
       }
      }
     }
  
     callStr = callStr.slice(0, -1);
     argsStr = argsStr.slice(0, -1);
  
     _ret = Function(argsStr, 'return function(){ return _fn' + callStr + ') }').apply(null, nonConstArgs);
    }
  
    _ret.prototype = _fn.prototype;
  
    return _ret;
   };
  })();
  
  this._basicBind = function(_fn, that, args) {
   var _ret;
  
   if (that !== defaultThis) {
    _ret = (args != null) ?
    function() {
     return _fn.apply(that, args);
    } : function() {
     return (arguments.length > 0) ? _fn.apply(that, arguments) : _fn.call(that);
    };
   }
   else {
    _ret = (args != null) ?
    function() {
     return _fn.apply(this, args);
    } : function() {
     return (arguments.length > 0) ? _fn.apply(this, arguments) : _fn.call(this);
    };
   }
  
   _ret.prototype = _fn.prototype;
  
   return _ret;
  };
  
  var _fn = function(a, b, c) {
   return a + b + c;
  };
  
  var args = [1, '',
  {},
  null, function() {}];
  
  var _native = (_fn.bind) ? _fn.bind.apply(_fn, [window].concat(args)) : null;
  var _basic = _basicBind(_fn, window, args);
  var _fast = _fastBind(_fn, window, args);
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Native
_native();
ready
Basic
_basic();
ready
Fast
_fast();
ready

Revisions

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

  • Revision 1: published by John-David Dalton on