Почему итерация через массив происходит быстрее, чем вперед
Учитывая этот код
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
Ответы
Ответ 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++;