Why is lodash.each faster than native forEach?

前端 未结 4 1999
别跟我提以往
别跟我提以往 2020-12-04 14:16

I was trying to find the fastest way of running a for loop with its own scope. The three methods I compared were:

var a = \"t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t         


        
4条回答
  •  情书的邮戳
    2020-12-04 14:26

    Yes, lodash/underscore each don't even have same semantics as .forEach. There is a subtle detail that will make the function really slow unless the engine can check for sparse arrays without getters quickly.

    This will be 99% spec compliant and runs at the same speed as lodash each in V8 for the common case:

    function FastAlmostSpecForEach( fn, ctx ) {
        "use strict";
        if( arguments.length > 1 ) return slowCaseForEach();
        if( typeof this !== "object" ) return slowCaseForEach();
        if( this === null ) throw new Error("this is null or not defined");
        if( typeof fn !== "function" ) throw new Error("is not a function");
        var len = this.length;
        if( ( len >>> 0 ) !== len ) return slowCaseForEach();
    
    
        for( var i = 0; i < len; ++i ) {
            var item = this[i];
            //Semantics are not exactly the same,
            //Fully spec compliant will not invoke getters
           //but this will.. however that is an insane edge case
            if( item === void 0 && !(i in this) ) {
                continue;
            }
            fn( item, i, this );
        }
    }
    
    Array.prototype.fastSpecForEach = FastAlmostSpecForEach;
    

    By checking for undefined first, we don't punish normal arrays in the loop at all. An engine could use its internals to detect strange arrays but V8 doesn't.

提交回复
热议问题