Подтвердить что ты не робот

Почему итерация через массив происходит быстрее, чем вперед

Учитывая этот код

   var arr = [];
    for (var i = 0; i < 10000; ++i) {
      arr.push(1);
    }

Нападающие

for (var i = 0; i < arr.length; ++i) {;
}

Backwards

for (var i = arr.length - 1; i >= 0; --i) {;
}

Жесткая кодированная передача

for (var i = 0; i < 10000; ++i) {;
}

почему бэкдд так намного быстрее?

Вот тест http://jsperf.com/array-iteration-direction

4b9b3361

Ответ 1

Поскольку ваше форвард-условие должно получать свойство length вашего массива каждый раз, в то время как другому условию нужно только проверять "больше нуля", очень быструю задачу.

Когда длина вашего массива не изменяется во время цикла, и вы действительно смотрите на ns-perfomance, вы можете использовать

for (var i=0, l=arr.length; i<l; i++)

BTW: Вместо for (var i = arr.length; i > 0; --i) вы можете использовать for (var i = arr.length; i-- > 0; ), который действительно проходит через ваш массив от n-1 до 0, а не от n до 1.

Ответ 2

Потому что в первом виде вы получаете доступ к свойству length массива arr один раз для каждой итерации, тогда как во втором вы делаете это только один раз.

Ответ 3

Если вы хотите иметь их в одинаковом темпе, вы можете сделать это для дальнейшей итерации;

for(var i=0, c=arr.length; i<c; i++){
}

Итак, вашему script не нужно будет занимать длину массива на everystep.

Ответ 4

Я не совсем уверен в этом, но вот моя догадка:

Для следующего кода:

for (var i = 0; i < arr.length; ++i) {;
}

В течение времени выполнения, после каждого прохождения цикла, выполняется вычисление arr.length. Это может быть тривиальной операцией, когда она стоит одна, но может иметь влияние, когда дело касается множества/огромных массивов. Можете ли вы попробовать следующее:

 var numItems = arr.length;
    for(var i=0; i< numItems; ++i)
    {
    }

В приведенном выше коде мы вычисляем длину массива только один раз и работаем с этим вычисленным числом, а не выполняем вычисления длины снова и снова.

Опять же, просто поместив мои мысли здесь. Интересное наблюдение действительно!

Ответ 5

i > 0 быстрее, чем i < arr.length и происходит на каждой итерации цикла.

Вы можете смягчить эту разницу:

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

Это все еще не так быстро, как обратный элемент, но быстрее, чем ваш прямой вариант.

Ответ 6

сделайте это, как показано ниже, он будет работать таким же образом. потому что arr.length занимает время на каждой итерации вперед.

int len = arr.length;

вперед

for (var i = 0; i < len; ++i) {
}

назад

for (var i = len; i > 0; --i) {
}

Ответ 7

И это одинаково хорошо:

var arr= [], L= 10000;
while(L>-1) arr[L]= L--;

ИЛИ

var arr= [], i= 0;
while(i<10001) arr[i]=i++;