array.forEach running faster than native iteration? How?

前端 未结 5 845
隐瞒了意图╮
隐瞒了意图╮ 2021-02-08 19:38

http://jsperf.com/testing-foreach-vs-for-loop

It was my understanding that Test Case 2 should run more slowly than Test Case 1 -- I wanted to see how much more slowly. I

相关标签:
5条回答
  • 2021-02-08 20:09

    Reading length from array at each iteration may be slow, but forEach is comomonly slower, cause function call isn't cheap operation in js.

    PS: forEach is 14% slower on FF10.

    0 讨论(0)
  • 2021-02-08 20:13

    Maybe the for() is slower because the loop applies 'array.length' to each iteration, to get the array's length.

    Try:

    var nri = array.length;
    for( var i = 0; i < nri; i++ ){
       // ...
    }
    
    0 讨论(0)
  • 2021-02-08 20:22

    UPDATE:

    A lot of the old tricks in these answers are great for interpreted JS in older browsers.

    In any modern JS implementation including all modern browsers, Node, and the latest mobile webviews, inline functions can actually be cached by the JIT (JS compiler), making forEach a much faster option for array iteration, typically. It used to be the opposite where just making calls to a function repeatedly required a build-up/teardown process that could severely diminish performance of a non-trivial loop.

    For best performance I'd avoid referencing anything that wasn't passed as an argument or defined inside the function itself if you don't have to. I'm not 100% sure that matters but I could see why it might.

    Getter values that involve any kind of lookup process like array lengths or DOM node properties are probably also still best cached to a variable.

    But beyond that I'd try to just let the basic principle of work avoidance guide your perf efforts. Pre-calculating things that don't need to be recalculated in a loop, or caching a query selector result to var rather than rummaging in the DOM repeatedly are good examples of this. Trying too hard to take advantage of JIT behavior is probably going to get pretty arcane and not likely to hold up over time or across all JITs.

    OLD ANSWER:

    Okay, forget wall of text. Bullet points:

    var i = someArray.length; //length is cached
    someArray.reverse(); //include this only if iterating in 0-(length-1) order is important
    
    while(i--){
    //run a test statement on someArray[i];
    }
    
    • length is cached and immediately made into the index

    • The benefit of iterating backwards in JS AFAIK is avoiding a logical operator with two operands. In this case we're just evaluating a number. It's true or it's zero and false.

    • I also find it elegant.

    0 讨论(0)
  • 2021-02-08 20:34

    They're approximately the same for me in Opera. Something to note is that your conditional in the for() is array.length. If you cache the length of the array in a variable, and then loop, you should see better performance.

    0 讨论(0)
  • 2021-02-08 20:35

    There are many iteration optimizations that your for loop is missing such as:

    • cache the array length
    • iterate backwards
    • use ++counter instead of counter++

    These are the ones that I have heard of and used, I am sure there are more. If memory serves me correct, the backwards iterating while loop is the fastest of all looping structures (in most browsers).

    See this jsperf for some examples.

    Edit: links for postfix vs prefix perf test and iterating backwards. I was not able to find my reference for using +=1 instead of ++, so I have removed it from the list.

    0 讨论(0)
提交回复
热议问题