function calls: direct vs apply vs call vs bind (v60)

Revision 60 of this benchmark created by Mark on


Setup

function f() {
        return this;
    }
    var that = {
        f: f
    };
    var bound = f.bind(that);
    var that2 = Object.create(that);
    var that3 = {};
    var that4 = Object.create(that3);
    
    function bind( fn, scope ){
        var args = ( arguments.length > 2 ) ? [].slice.call( arguments, 2 ) : []
          ;
    
        return function(){
                var argList = arguments.length ? args.slice() : args;
    
                for( var i=0, l=arguments.length; i<l; i++ ){
                        argList.push( arguments[i] );
                }
    
                var numArgs = argList.length;
    
                return (
                        ( numArgs < 10 )
                                ? scope
                                        ? (
                                                  ( 0 === numArgs ) ? fn.call( scope )
                                                : ( 1 === numArgs ) ? fn.call( scope, argList[0] )
                                                : ( 2 === numArgs ) ? fn.call( scope, argList[0], argList[1] )
                                                : ( 3 === numArgs ) ? fn.call( scope, argList[0], argList[1], argList[2] )
                                                : ( 4 === numArgs ) ? fn.call( scope, argList[0], argList[1], argList[2], argList[3] )
                                                : ( 5 === numArgs ) ? fn.call( scope, argList[0], argList[1], argList[2], argList[3], argList[4] )
                                                : ( 6 === numArgs ) ? fn.call( scope, argList[0], argList[1], argList[2], argList[3], argList[4], argList[5] )
                                                : ( 7 === numArgs ) ? fn.call( scope, argList[0], argList[1], argList[2], argList[3], argList[4], argList[5], argList[6] )
                                                : ( 8 === numArgs ) ? fn.call( scope, argList[0], argList[1], argList[2], argList[3], argList[4], argList[5], argList[6], argList[7] )
                                                : ( 9 === numArgs ) ? fn.call( scope, argList[0], argList[1], argList[2], argList[3], argList[4], argList[5], argList[6], argList[7], argList[8] )
                                                : '' // can't get here
                                        )
                                        : (
                                                  ( 0 === numArgs ) ? fn()
                                                : ( 1 === numArgs ) ? fn( argList[0] )
                                                : ( 2 === numArgs ) ? fn( argList[0], argList[1] )
                                                : ( 3 === numArgs ) ? fn( argList[0], argList[1], argList[2] )
                                                : ( 4 === numArgs ) ? fn( argList[0], argList[1], argList[2], argList[3] )
                                                : ( 5 === numArgs ) ? fn( argList[0], argList[1], argList[2], argList[3], argList[4] )
                                                : ( 6 === numArgs ) ? fn( argList[0], argList[1], argList[2], argList[3], argList[4], argList[5] )
                                                : ( 7 === numArgs ) ? fn( argList[0], argList[1], argList[2], argList[3], argList[4], argList[5], argList[6] )
                                                : ( 8 === numArgs ) ? fn( argList[0], argList[1], argList[2], argList[3], argList[4], argList[5], argList[6], argList[7] )
                                                : ( 9 === numArgs ) ? fn( argList[0], argList[1], argList[2], argList[3], argList[4], argList[5], argList[6], argList[7], argList[8] )
                                                : '' // can't get here
                                        )
                                : fn.apply( scope, argList )
                );
        }
    }
    
    var bound2 = bind( f, that );
    var bound3 = bind( f );

Test runner

Ready to run.

Testing in
TestOps/sec
direct
that.f();
ready
apply
f.apply(that);
ready
call
f.call(that);
ready
bind
bound();
ready
prototype
that2.f();
ready
direct (dynamic property)
that3.f = f; that3.f();
ready
prototype (dynamic property)
that3.f = f; that4.f();
ready
fast bind
bound2();
ready
bind, no scope
bound3();
ready

Revisions

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