Для переменных цикла в javascript
В этот веб-сайт содержит список вариантов цикла. Я могу понять использование цикла for(var i=0, len=arr.length; i<len ;i++)
(где arr
- массив), поскольку arr.length
не вычисляется на каждом шаге, как представляется, существует предельное увеличение производительности. Однако каковы преимущества использования других вариантов? Например, такие петли, как
-
for (var i=arr.length; i--;)
-
for (var i=0, each; each = arr[i]; i++)
Есть ли заметные изменения в производительности, используя разные варианты цикла? Обычно я использую for(var i=0, len=arr.length; i<len ;i++)
даже для очень больших массивов. Поэтому я просто хочу знать, есть ли что-то, чего я здесь не хватает.
Ответы
Ответ 1
Широко считается, что обратный цикл while
var loop = arr.length;
while( loop-- ) {
}
- это самый быстрый тип цикла, доступный на языках C-типа (это также довольно давно применяется к ECMAscript, но я думаю, что все современные двигатели сегодня даже на стандартных циклах). (jsperf)
Ваши "вариации" на самом деле не являются вариациями, а просто отличаются от оператора conditional
в for-loop
(что фактически делает его вариацией..doh!). Как
1) for (var i=arr.length; i--;)
Просто использует условную часть из for-loop
для выполнения обоих операций, итерации и проверки, если i
имеет правдивое значение. Как только i
станет 0
, цикл завершится.
2) for (var i=0, each; each = arr[i]; i++)
Здесь мы получаем элемент из каждой итерации, поэтому мы можем напрямую обращаться к нему в теле цикла. Это обычно используется, когда вы устали от повторения arr[ n ]
.
Вы преуспеваете в кэшировании свойства .length
перед циклом. Как вы правильно сказали, это быстрее, потому что нам не нужно получать доступ к этому свойству на каждой итерации. Помимо этого, он также иногда требуется в сценариях DOM, когда речь идет о "живых структурах", таких как HTMLCollections
.
Ответ 2
Дело в том, что вы уменьшаете итератор, вы фактически сравниваете его с 0, а не по длине, что быстрее, поскольку операторы "<, < =, > , > =" требуют проверки типа на как левая, так и правая стороны оператора, чтобы определить, какое поведение сравнения следует использовать.
самый быстрый цикл: (Если вы, конечно, не заботитесь о порядке)
var i = arr.length
while(i--)
{
}
Если вы заботитесь о заказе, метод, который вы используете, в порядке.
Ответ 3
Согласно jsperf, самый быстрый тип цикла в JavaScript -
var arr = new Array(10);
var i = 0;
while (i < arr.length) {
arr[i];
i++;
};
только впереди (мой цикл по умолчанию)
var arr = new Array(10);
for (var i = 0; i < arr.length; ++i) {
arr[i];
};
При этом самый медленный:
var arr = new Array(10);
arr.forEach(function(x) {
x;
});
по крайней мере на Chrome 17 на OSX 10.7.3. Так что кажется, что цикл "по умолчанию" в конце концов прекрасен!!!
Ответ 4
Это плохое использование a для каждого цикла, потому что оно будет терпеть неудачу по значениям ложности, нарушая цикл.
for (var i=0, each; each = arr[i]; i++)
Я тоже не буду использовать этот цикл (даже жестко это может быть быстрее...)
for (var i=arr.length; i--;)
Он выглядит запутанным и менее читаемым, вы также можете писать как обратный цикл while.