Do loops check the array.length every time when comparing i against array.length?

I was browsing around and I found this:

var i, len;
for(i = 0, len = array.length; i < len; i++) {  
   //...
}

My first thoughts are:

  • Why he did that? (it must be better for some reason)
  • Is it worth it? (I assume yes, why else he will do it this way?)
  • Do normal loops (the ones that don't cache the length) check the array.length each time?


    A loop consisting of three parts is executed as follows:

    for (A; B; C)
    
    A - Executed before the enumeration
    B - condition to test
    C - expression after each enumeration (so, not if B evaluated to false)
    

    So, yes: The .length property of an array is checked at each enumeration if it's constructed as for(var i=0; i<array.length; i++) . For micro-optimisation, it's efficient to store the length of an array in a temporary variable (see also: What's the fastest way to loop through an array in JavaScript?).

    Equivalent to for (var i=0; i<array.length; i++) { ... } :

    var i = 0;
    while (i < array.length) {
        ...
        i++;
    }
    

    Is it worth it? (obviously yes, why else he will do it this way?)

    Absolutely yes. Because, as you say, loop will calculate array length each time. So this will cause an enormous overhead. Run the following code snippets in your firebug or chrome dev tool vs.

    // create an array with 50.000 items
    (function(){
        window.items = [];
        for (var i = 0; i < 50000; i++) {
            items.push(i);
        }
    })();
    
    // a profiler function that will return given function's execution time in milliseconds
    var getExecutionTime = function(fn) {
        var start = new Date().getTime();
        fn();
        var end = new Date().getTime();
        console.log(end - start);
    }
    
    var optimized = function() {
        var newItems = [];
        for (var i = 0, len = items.length; i < len; i++) {
            newItems.push(items[i]);
        }
    };
    
    
    var unOptimized = function() {
        var newItems= [];
        for (var i = 0; i < items.length; i++) {
            newItems.push(items[i]);
        }
    };
    
    getExecutionTime(optimized);
    getExecutionTime(unOptimized);
    

    Here is the approximate results in various browsers

    Browser    optimized    unOptimized
    Firefox    14           26
    Chrome     15           32
    IE9        22           40
    IE8        82           157
    IE7        76           148 
    

    So consider it again, and use optimized way :)
    Note: I tried to work this code on jsPerf but I couldn't access jsPerf now. I guess, it is down when I tried.


  • if array.length is a calculated value (unlikely in your example) then it is better to retrieve the value one time and store it in a variable.

  • if array.length is not calculated (likely the case in your example) then it is of no value to retrieve the length and store it in a variable.

  • 链接地址: http://www.djcxy.com/p/59046.html

    上一篇: 如何使用超时分派Redux动作?

    下一篇: 每次比较我和array.length时,Do循环是否检查array.length?