Для вариаций цикла в JavaScript - PullRequest
13 голосов
/ 30 марта 2012

На этом веб-сайте есть список вариантов цикла. Я могу понять использование цикла for(var i=0, len=arr.length; i<len ;i++) (где arr - массив), так как arr.length не рассчитывается на каждом шаге, там, как представляется, незначительное увеличение производительности. Однако каковы преимущества использования других вариантов? Например, петли типа

  1. for (var i=arr.length; i--;)
  2. for (var i=0, each; each = arr[i]; i++)

Существуют ли какие-либо заметные изменения в производительности при использовании разных вариаций цикла? Я обычно использую for(var i=0, len=arr.length; i<len ;i++) даже для очень больших массивов. Так что я просто хочу знать, есть ли здесь что-то, чего мне не хватает.

Ответы [ 4 ]

7 голосов
/ 30 марта 2012

Считается, что обратный цикл while

var loop = arr.length;
while( loop-- ) {
}

- самый быстрый тип цикла, доступный в C-подобных языках (он также применялся к ECMAscript довольно долгое время, но я думаю, что все современные движки довольно хороши даже сегодня на стандартных циклах). ( jsperf )

Ваши 'вариации' на самом деле не вариации, а просто другое использование оператора conditional в пределах for-loop (что фактически делает его вариацией ... да!). Нравится

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 голосов
/ 30 марта 2012

Согласно 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.Так что кажется, что цикл «по умолчанию» в конце концов хорош !!!

2 голосов
/ 30 марта 2012

Дело в том, что когда вы уменьшаете итератор, вы фактически сравниваете его с 0, а не с длиной, что быстрее, поскольку операторы "<, <=,>,> =" требуют проверки типов слева и справа от оператора, чтобы определить, какое поведение сравнения следует использовать.

самый быстрый цикл: (если вы не заботитесь о порядке, конечно)

var i = arr.length
while(i--)
{
}

Если вы заботитесь о заказе, вы можете использовать метод, который вам подходит.

1 голос
/ 30 марта 2012

Это плохое использование a для каждого цикла, потому что он потерпит неудачу при ложных значениях, нарушая цикл.

for (var i=0, each; each = arr[i]; i++)

Я бы тоже не использовал этот цикл (даже если он может быть быстрее ...)

for (var i=arr.length; i--;)

Это выглядит сбивающим с толку и менее читабельным, тогда вы могли бы написать так же, как и обратный цикл while.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...