Для переменных цикла в 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.