Действительно ли циклы быстрее в обратном направлении?

Я слышал это довольно много раз. Действительно ли JavaScript-контуры быстрее при подсчете назад? Если да, то почему? Я видел несколько примеров набора тестов, показывающих, что обратные циклы быстрее, но я не могу найти объяснений относительно того, почему!

Я предполагаю это, потому что цикл больше не должен оценивать свойство каждый раз, когда он проверяет, завершен ли он, и он просто проверяет окончательное числовое значение.

т.е.

for (var i = count - 1; i >= 0; i--)
{
  // count is only evaluated once and then the comparison is always on 0.
}

Ответ 1

Это не то, что i-- быстрее, чем i++. На самом деле, они оба одинаково быстры.

То, что занимает время в восходящих циклах, оценивает для каждого i размер вашего массива. В этом цикле:

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

Вы оцениваете .length только один раз, когда объявляете i, тогда как для этого цикла

for(var i = 1; i <= array.length; i++)

вы оцениваете .length каждый раз, когда вы увеличиваете i, когда вы проверяете, есть ли i <= array.length.

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

Ответ 2

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

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

var i = arr.length; //or 10
while(i--)
{
  //...
}

Ответ 3

Я пытаюсь дать широкую картину с этим ответом.

Следующие мысли в скобках были моими убеждениями, пока я только недавно не протестировал проблему:

[[В терминах языков низкого уровня, например C/C++, код компилируется так, что процессор имеет специальную команду условного перехода, когда переменная равна нулю (или не равна нулю).
Кроме того, если вы заботитесь об этой оптимизации, вы можете пойти ++i вместо i++, потому что ++i - это команда с одним процессором, тогда как i++ означает j=i+1, i=j.]]

Действительно быстрые петли можно выполнить, развернув их:

for(i=800000;i>0;--i)
    do_it(i);

Это может быть медленнее, чем

for(i=800000;i>0;i-=8)
{
    do_it(i); do_it(i-1); do_it(i-2); ... do_it(i-7);
}

но причины этого могут быть довольно сложными (просто отметим, что есть проблемы с предварительной обработкой процессора и обработкой кеша в игре).

В терминах языков высокого уровня, например JavaScript, вы можете оптимизировать вещи, если вы полагаться на библиотеки, встроенные функции для циклизации. Пусть они решают, как это лучше всего сделать.

Следовательно, в JavaScript я бы предложил использовать что-то вроде

array.forEach(function(i) {
    do_it(i);
});

Он также менее подвержен ошибкам, и браузеры имеют возможность оптимизировать ваш код.

[Замечание: не только браузеры, но и у вас тоже есть свободное пространство для оптимизации, просто переопределите функцию forEach (браузер зависит от пользователя), чтобы она использовала самую последнюю хитрость!:) @A.M.K. говорит, что в особых случаях стоит использовать array.pop или array.shift. Если вы сделаете это, положите его за занавес. Наибольший избыток - это добавить опции forEach, чтобы выбрать алгоритм цикла.]

Кроме того, для языков низкого уровня лучше всего использовать некоторую функцию умной библиотеки для сложных, замкнутых операций, если это возможно.

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

Я сделал немного больше внимания, и выясняется, что в C/С++, даже для операций 5e9 = (50,000x100,000), нет разницы между движением вверх и вниз, если тестирование выполняется против константы, например, @alestanis. (Результаты JsPerf иногда противоречивы, но по большому счету говорят одно и то же: вы не можете иметь большого значения.)
Так что --i оказывается скорее "шикарным". Это только заставляет вас выглядеть лучше программистом.:)

С другой стороны, для-разворачивания в этой ситуации 5e9, это привело меня с 12 до 5 секунд, когда я пошел на 10 секунд и до 2,1 секунды, когда я пошел на 20 секунд. Это было без оптимизации, и оптимизация привела к невероятному малому времени.:) (Unrolling можно сделать по-моему выше или с помощью i++, но это не приносит вещи в JavaScript.)

В целом: сохраняйте различия i--/i++ и ++i/i++ в собеседовании по заданию, придерживайтесь array.forEach или других сложных библиотечных функций, когда они доступны.;)

Ответ 4

i-- выполняется так же быстро, как i++

Этот код ниже так же быстро, как ваш, но использует дополнительную переменную:

var up = Things.length;
for (var i = 0; i < up; i++) {
    Things[i]
};

Рекомендация состоит в том, чтобы НЕ оценивать размер массива каждый раз. Для больших массивов можно увидеть ухудшение производительности.

Ответ 5

Так как вас интересует тема, посмотрите статью в блоге Greg Reimer о тесте цикла JavaScript, Какой самый быстрый способ кодировать цикл в JavaScript:

Я построил тестовый набор тестов цикла для разных способов кодирования в JavaScript. Их уже много, но я не нашел ни одного, кто признал бы разницу между встроенными массивами и коллекциями HTML.

Вы также можете выполнить тест производительности в цикле, открыв https://blogs.oracle.com/greimer/resource/loop-test.html (не работает, если JavaScript заблокирован в браузере, например, NoScript).

EDIT:

Более поздний эталон, созданный Миланом Адамовским, можно выполнить в режиме здесь для разных браузеров.

Для Тестирования в Firefox 17.0 на Mac OS X 10.6 Я получил следующий цикл:

var i, result = 0;
for (i = steps - 1; i; i--) {
  result += i;
}

как наиболее быстрый, предшествующий:

var result = 0;
for (var i = steps - 1; i >= 0; i--) {
  result += i;
}

Benchmark example.

Ответ 6

Это не -- или ++, это операция сравнения. С -- вы можете использовать сравнение с 0, а при ++ вам нужно сравнить его с длиной. На процессоре обычно сравнивается с нулем, в то время как сравнение с конечным целым требует вычитания.

a++ < length

фактически скомпилирован как

a++
test (a-length)

Поэтому при компиляции процессор занимает больше времени.

Ответ 7

Короткий ответ

Для нормального кода, особенно на языке высокого уровня, например JavaScript, в i++ и i-- нет разницы в производительности.

Критерии эффективности - это использование в цикле for и инструкции сравнения.

Этот применяется ко всем языкам высокого уровня и в основном не зависит от использования JavaScript. Объяснение - это итоговый код ассемблера в нижней строке.

Подробное объяснение

В цикле может произойти различие в производительности. Фон состоит в том, что на уровне ассемблерного кода вы можете видеть, что a compare with 0 - это всего лишь один оператор, который не нуждается в дополнительном регистре.

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

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

будет оцениваться псевдокодом следующим образом:

 i=array.length
 :LOOP_START
 decrement i
 if [ i = 0 ] goto :LOOP_END
 ... BODY_CODE
 :LOOP_END

Обратите внимание, что 0 является литералом, или, другими словами, постоянным значением.

for(var i = 0 ; i < array.length; i++ )

будет оцениваться как псевдокод (предположим, что предполагается нормальная интерпретация интерпретатора):

 end=array.length
 i=0
 :LOOP_START
 if [ i < end ] goto :LOOP_END
 increment i
 ... BODY_CODE
 :LOOP_END

Обратите внимание, что end - это переменная, которая нуждается в регистрации CPU. Это может вызвать дополнительную регистрацию кода в коде и требует более дорогого оператора сравнения в инструкции if.

Только мои 5 центов

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

Обычно классическая итерация от начала до конца лучше.

Более быстрая итерация от конца массива до начала приводит к возможной нежелательной обратной последовательности.

Post scriptum

Как задано в комментарии: Разница --i и i-- заключается в оценке i до или после декремента.

Лучшее объяснение - попробовать:-) Вот пример Bash.

 % i=10; echo "$((--i)) --> $i"
 9 --> 9
 % i=10; echo "$((i--)) --> $i"
 10 --> 9

Ответ 8

Я видел ту же рекомендацию в Sublime Text 2.

Как уже было сказано, основное улучшение не оценивает длину массива на каждой итерации в цикле for. Это хорошо известный метод оптимизации и особенно эффективен в JavaScript, когда массив является частью HTML-документа (выполняет for для всех элементов li).

Например,

for (var i = 0; i < document.getElementsByTagName('li').length; i++)

намного медленнее, чем

for (var i = 0, len = document.getElementsByTagName('li').length; i < len; i++)

С того места, где я стоял, основным улучшением формы в вашем вопросе является тот факт, что он не объявляет дополнительную переменную (len в моем примере)

Но если вы спросите меня, все дело не в оптимизации i++ vs i--, а в том, что не нужно оценивать длину массива на каждой итерации (вы можете увидеть тестовый тест на jsperf).

Ответ 9

Я не думаю, что имеет смысл сказать, что i-- быстрее, чем i++ в JavaScript.

Прежде всего, это полностью зависит от реализации JavaScript-движка.

Во-вторых,, при условии, что простейшие конструкции JIT'ed и переведенные на собственные команды, тогда i++ vs i-- будет полностью зависеть от процессора, который его выполняет. То есть, на ARM (мобильных телефонах) быстрее спускается до 0, так как декремент и сравнение с нолем выполняются в одной команде.

Вероятно, вы думали, что один был расточителем, чем другой, потому что предлагаемый способ

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

но предложенный способ не потому, что один быстрее, чем другой, а просто потому, что если вы пишете

for(var i = 0; i < array.length; i++)

то на каждой итерации array.length нужно было оценить (более умный движок JavaScript, возможно, мог бы выяснить, что цикл не изменит длину массива). Несмотря на то, что это выглядит как простой оператор, на самом деле это функция, вызываемая механизмом JavaScript под капотом.

Другая причина, почему i-- можно считать "быстрее", потому что JavaScript-движок должен выделять только одну внутреннюю переменную для управления циклом (переменная в var i). Если вы сравнили с array.length или с какой-либо другой переменной, тогда для управления циклом должно быть более одной внутренней переменной, а количество внутренних переменных - это ограниченный ресурс механизма JavaScript. Чем меньше переменных используется в цикле, тем больше вероятность JIT для оптимизации. Вот почему i-- можно было бы считать быстрее...

Ответ 10

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

Итак, вот вы:

Простой ответ: i-- обычно быстрее, потому что ему не нужно запускать сравнение до 0 при каждом запуске, результаты тестирования по различным методам ниже:

Результаты тестов: Как "проверено" this jsPerf, arr.pop() - фактически самый быстрый цикл на далеко. Но, сосредоточив внимание на --i, i--, i++ и ++i, как вы задали в своем вопросе, вот jsPerf (они из нескольких jsPerf's, см. Источники ниже). Результаты обобщены:

--i и i-- одинаковы в Firefox, а i-- быстрее в Chrome.

В Chrome базовый цикл (for (var i = 0; i < arr.length; i++)) быстрее, чем i-- и --i, в то время как в Firefox он медленнее.

В Chrome и Firefox кешированный arr.length значительно быстрее с Chrome впереди примерно на 170 000 оп/сек.

Без существенной разницы ++i быстрее, чем i++ в большинстве браузеров, AFAIK, в любом браузере это никогда не будет наоборот.

Сокращение: arr.pop() - самый быстрый цикл; для специально упомянутых контуров i-- является самым быстрым циклом.

Источники: http://jsperf.com/fastest-array-loops-in-javascript/15, http://jsperf.com/ipp-vs-ppi-2

Надеюсь, это ответит на ваш вопрос.

Ответ 11

Это зависит от размещения вашего массива в памяти и коэффициента попадания страниц памяти во время доступа к этому массиву.

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

Ответ 12

В последний раз я беспокоился об этом, когда писал 6502 сборку (8-бит, да!). Большой выигрыш в том, что большинство арифметических операций (особенно декрементов) обновили набор флагов, один из которых был Z, индикатор "достиг нулевого".

Итак, в конце цикла вы только что выполнили две команды: DEC (декремент) и JNZ (скачок, если не ноль), никакого сравнения не требуется!

Ответ 13

Сократить это: В JavaScript нет никакой разницы.

Прежде всего, вы можете проверить его самостоятельно:

Не только вы можете протестировать и запустить любой script в любой библиотеке JavaScript, но у вас также есть доступ ко всей группе ранее написанных скриптов, а также возможность видеть различия между временем выполнения в разных браузерах на разных платформах.

Итак, насколько вы можете видеть, нет никакой разницы между производительностью в любой среде.

Если вы хотите улучшить производительность своего script, то, что вы можете попробовать:

  • Имейте оператор var a = array.length;, чтобы вы не вычисляли его значение каждый раз в цикле
  • Развертывание цикла http://en.wikipedia.org/wiki/Loop_unwinding

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

Мое собственное мнение, почему появилось такое заблуждение (Dec vs Inc)

Долгое время назад была обычная машинная инструкция, DSZ (Decrement и Skip on Zero). Люди, запрограммированные на языке ассемблера, использовали эту инструкцию для реализации циклов, чтобы сохранить регистр. Теперь эти древние факты устарели, и я уверен, что вы не получите какого-либо улучшения производительности на любом языке, используя это псевдо-улучшение.

Я думаю, что единственный способ, которым такие знания могут распространяться в наше время, - это когда вы читаете код другого человека. Посмотрите на такую ​​конструкцию и спросите, почему она была реализована, и вот ответ: "она повышает производительность, потому что она сравнивается с нулем". Вы были в недоумении от более высокого знания своего коллеги и подумали использовать его гораздо умнее:-)

Ответ 14

Это может быть объяснено тем, что JavaScript (и все языки) в конечном итоге превращается в коды операций для запуска на CPU. ЦП всегда имеют единую инструкцию для сравнения с нулем, которая быстро работает.

Как в стороне, если вы можете гарантировать count всегда >= 0, вы можете упростить:

for (var i = count; i--;)
{
  // whatever
}

Ответ 15

Это не зависит от знака -- или ++, но зависит от условий, которые вы применяете в цикле.

Например: ваш цикл быстрее, если переменная имеет статическое значение, чем если бы каждый цикл проверял условия, такие как длина массива или другие условия.

Но не беспокойтесь об этой оптимизации, потому что на этот раз ее эффект измеряется в наносекундах.

Ответ 16

for(var i = array.length; i--; ) не намного быстрее. Но когда вы заменяете array.length на super_puper_function(), это может быть значительно быстрее (поскольку оно вызывалось на каждой итерации). Это различие.

Если вы собираетесь изменить его в 2014 году, вам не нужно думать об оптимизации. Если вы собираетесь изменить его с помощью "Поиск и замена", вам не нужно думать об оптимизации. Если у вас нет времени, вам не нужно думать об оптимизации. Но теперь у вас есть время подумать об этом.

P.S.: i-- не быстрее, чем i++.

Ответ 17

Иногда внесение некоторых незначительных изменений в способ написания нашего кода может иметь большое значение для быстрого выполнения нашего кода. Одна область, где незначительное изменение кода может существенно повлиять на время выполнения, - это то, где мы имеем цикл for, который обрабатывает массив. Если массив содержит элементы на веб-странице (например, радиокнопки), изменение имеет самый большой эффект, но все равно стоит применить это изменение, даже если массив является внутренним для кода Javascript.

Традиционный способ кодирования цикла for для обработки массива lis следующим образом:

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

Проблема заключается в том, что для вычисления длины массива с использованием myArray.length требуется время, и способ, которым мы закодировали цикл, означает, что эта оценка должна выполняться каждый раз вокруг цикла. Если массив содержит 1000 элементов, длина массива будет оцениваться 1001 раз. Если бы мы смотрели на переключатели и имели myForm.myButtons.length, это займет еще больше времени, так как соответствующая группа кнопок в указанной форме должна быть сначала расположена до того, как длина будет оцениваться каждый раз вокруг цикла.

Очевидно, мы не ожидаем, что длина массива изменится, пока мы его обрабатываем, поэтому все эти пересчеты длины просто излишне добавляют к времени обработки. (Конечно, если у вас есть код внутри цикла, который добавляет или удаляет записи массива, размер массива может меняться между итерациями, поэтому мы не можем изменить код, который его тестирует)

Что мы можем сделать, чтобы исправить это для цикла, где фиксирован размер, является оценка длины один раз в начале цикла и сохранение его в переменной. Затем мы можем проверить переменную, чтобы решить, когда завершить цикл. Это намного быстрее, чем оценка длины массива каждый раз, особенно когда массив содержит больше, чем просто несколько записей или является частью веб-страницы.

Код для этого:

for (var i = 0, var j = myArray.length; i < j; i++) {...

Итак, теперь мы только оцениваем размер массива один раз и проверяем наш счетчик циклов на переменную, которая хранит это значение каждый раз вокруг цикла. Эта дополнительная переменная может быть доступна гораздо быстрее, чем оценка размера массива, поэтому наш код будет работать намного быстрее, чем раньше. У нас есть только одна дополнительная переменная в script.

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

Последний код, который обрабатывает наш массив наиболее эффективным образом:

for (var i = myArray.length-1; i > -1; i--) {...

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

Ответ 18

То, как вы делаете это сейчас, не ускоряется (кроме того, что это неопределенный цикл, я думаю, вы хотели сделать i--.

Если вы хотите сделать это быстрее:

for (i = 10; i--;) {
    //super fast loop
}

конечно, вы не заметили бы этого на таком маленьком цикле. Причина в том, что это быстрее, потому что вы уменьшаете i, проверяя, что это "истина" (он оценивает "false", когда достигает 0)

Ответ 19

Я сделал сравнение в jsbench.

Как отмечал алестани, одна вещь, которая требует времени в восходящих петлях, заключается в том, чтобы оценить для каждой итерации размер вашего массива. В этом цикле:

for ( var i = 1; i <= array.length; i++ )

вы оцениваете .length каждый раз, когда вы увеличиваете i. В этом:

for ( var i = 1, l = array.length; i <= l; i++ )

вы оцениваете .length только один раз, когда объявляете i. В этом:

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

сравнение неявно, оно происходит непосредственно перед декрементом i, и код очень читабельен. Однако, что может сделать потрясающую разницу, это то, что вы вложили в цикл.

Петля с вызовом функции (определенная в другом месте):

for (i = values.length; i-- ;) {
  add( values[i] );
}

Петля со встроенным кодом:

var sum = 0;
for ( i = values.length; i-- ;) {
  sum += values[i];
}

Если вы можете встроить свой код вместо вызова функции, не жертвуя удобочитаемостью, вы можете иметь цикл на порядок быстрее!


Примечание: в качестве браузера становится хорошим при встраивании простых функций, это действительно зависит от того, насколько сложный код является. Итак, профиль перед оптимизацией, потому что

  • Узкое место может быть в другом месте (ajax, reflow,...)
  • Вы можете выбрать лучший алгоритм
  • Вы можете выбрать лучшую структуру данных

Но помните:

Код написан для чтения людьми, и только случайно для машин для выполнения.

Ответ 20

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

Это потому, что только несколько движков Javascript (те, что в списке JIT) фактически генерируют код машинного языка.

Большинство движков Javascript строят внутреннее представление исходного кода, который они затем интерпретируют (чтобы понять, что это такое, посмотрите в нижней части эту страницу на Firefox SpiderMonkey). Обычно, если кусок кода делает практически одно и то же, но приводит к более простому внутреннему представлению, он будет работать быстрее.

Помните, что с помощью простых задач, таких как добавление/вычитание одного из переменной или сравнение переменной с чем-то, накладные расходы переводчика, перемещающегося из одной внутренней "инструкции" на другую, довольно высоки, поэтому менее "инструкции" "которые используются внутри двигателя JS, тем лучше.

Ответ 21

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

В низкоуровневой сборке есть инструкция цикла, называемая DJNZ (декремент и прыжок, если отличная от нуля). Таким образом, декремент и прыжок все в одной инструкции, что делает его, возможно, когда-либо немного быстрее, чем INC и JL/JB (приращение, прыжок, если меньше или прыгать, если ниже). Кроме того, сравнение с нулем проще, чем сравнение с другим числом. Но все это действительно маргинально, а также зависит от целевой архитектуры (может отличаться, например, от руки в смартфоне).

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

Ответ 22

Раньше говорилось, что -i был быстрее (на С++), потому что есть только один результат - декрементированное значение. i-- нужно сохранить уменьшенное значение обратно в i, а также сохранить исходное значение в результате (j = i--;). В большинстве компиляторов это использовало два регистра, а не один, что могло бы привести к тому, что другая переменная должна быть записана в память, а не сохранена как переменная регистра.

Я согласен с теми, кто сказал, что в наши дни это не имеет значения.

Ответ 23

Не много времени потребляется i- или я ++. Если вы заходите глубоко внутри архитектуры ЦП, ++ быстрее, чем --, так как операция -- будет выполнять 2 дополнения, но это происходит внутри аппаратного обеспечения, поэтому это сделает его быстрым и не будет иметь существенной разницы между ++ и -- также эти операции считаются наименее затраченными в CPU.

для цикла выполняется следующим образом:

  • Инициализировать переменную один раз в начале.
  • Проверьте ограничение во втором операнде цикла, <, >, <= и т.д.
  • Затем примените цикл.
  • Приращивание цикла и цикла снова повторяет эти процессы.

Итак,

for (var i = Things.length - 1; i >= 0; i--) {
    Things[i]
}; 

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

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

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

Ответ 24

Во-первых, i++ и i-- принимают одинаковое время на любом языке программирования, включая JavaScript.

Следующий код занимает совсем другое время.

Быстро:

for (var i = 0, len = Things.length - 1; i <= len; i++) { Things[i] };

Slow:

for (var i = 0; i <= Things.length - 1; i++) { Things[i] };

Поэтому следующий код также принимает другое время.

Быстро:

for (var i = Things.length - 1; i >= 0; i--) { Things[i] };

Slow:

for (var i = 0; i <= Things.length - 1; i++) { Things[i] };

P.S. Медленное медленное только для нескольких языков (движков JavaScript) из-за оптимизации компилятора. Лучший способ - использовать '<' вместо этого '< =' (или '=') и '- i' вместо 'i -'.

Ответ 25

В очень простых словах

"i-- и я ++. На самом деле, они оба берут одно и то же время".

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

Ответ 26

++ vs. -- не имеет значения, поскольку JavaScript является интерпретированным языком, а не компилируемым языком. Каждая инструкция переводится на несколько машинных языков, и вам не нужно заботиться о деталях gory.

Люди, которые говорят об использовании -- (или ++) для эффективного использования инструкций по сборке, ошибочны. Эти инструкции относятся к целочисленной арифметике и нет целых чисел в JavaScript, просто числа.

Вы должны написать читаемый код.

Ответ 27

Лучший способ ответить на этот вопрос - это попробовать. Настройте цикл, который насчитывает миллион итераций или что-то еще, и делайте это в обоих направлениях. Время и петли, и сравнение результатов.

Ответ, вероятно, будет зависеть от того, какой браузер вы используете. Некоторые будут иметь разные результаты, чем другие.

Ответ 28

Люблю это, много знаков, но ответа нет: D

Проще говоря сравнение с нулем всегда самое быстрое сравнение

Итак (a == 0) на самом деле быстрее возвращается True, чем (a == 5)

Он маленький и незначительный и со 100 миллионами строк в коллекции, который он измерил.

i.e на петле вы можете сказать, где я <= array.length и увеличивать i

в нисходящем цикле вы можете сказать, где я >= 0 и вместо этого уменьшайте i.

Сравнение выполняется быстрее. Не "направление" цикла.

Ответ 29

ПОМОЩЬ ДРУГИЕ ИЗБЕГАЮТ ГОЛОВКУ --- ГОЛОСОВАТЬ ЭТОТ!!!!

Самый популярный ответ на этой странице не работает для Firefox 14 и не передает jsLinter. "while" циклам нужен оператор сравнения, а не задание. Он работает на хроме, сафари и т.д. Но умирает в firefox.

ЭТО БРОКЕН!

var i = arr.length; //or 10
while(i--)
{
  //...
}

ЭТО БУДЕТ РАБОТАЕТ! (работает на firefox, передает jsLinter)

var i = arr.length; //or 10
while(i>-1)
{
  //...
  i = i - 1;
}

Ответ 30

Это просто предположение, но, возможно, потому, что процессору проще сравнивать что-то с 0 (i >= 0) вместо другого значения (i < Things.length).