Я пытаюсь дать общую картину с этим ответом.
Следующие мысли в скобках были моей верой, пока я только недавно не проверил проблему:
[[В терминах языков низкого уровня, таких как 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
функцию (в зависимости от браузера), чтобы она использовала новейшие хитрости! :) @AMK говорит, что в особых случаях стоит использовать array.pop
or array.shift
. Если вы сделаете это, положите его за занавес. Самое лишнее - добавить опции forEach
для выбора алгоритма зацикливания.]
Более того, для языков низкого уровня рекомендуется использовать некоторую интеллектуальную библиотечную функцию для сложных циклических операций, если это возможно.
Эти библиотеки также могут помещать вещи (многопоточные) за вашу спину, а также специализированные программисты поддерживают их актуальность.
Я провел более тщательную проверку, и оказалось, что в C / C ++, даже для операций 5e9 = (50,000x100,000), нет никакой разницы между повышением и понижением, если тестирование выполняется с константой, как говорит @alestanis. (Результаты JsPerf иногда противоречивы, но, по большому счету, говорят одно и то же: вы не можете иметь большого значения.)
Так --i
что это скорее «шикарная» вещь. Это только делает вас похожим на лучшего программиста. :)
С другой стороны, для разворачивания в этой ситуации 5e9 это снизило меня с 12 секунд до 2,5 секунд, когда я шел на 10 секунд, и до 2,1 секунд, когда я шел на 20 секунд. Это было без оптимизации, а оптимизация привела к невообразимому небольшому времени. :) (Развертывание может быть сделано моим способом выше или с использованием i++
, но это не продвигает вещи вперед в JavaScript.)
В целом: сохраняйте i--
/ i++
и ++i
/ или i++
отличия от собеседований при приеме на работу, придерживайтесь array.forEach
или выполняйте другие сложные библиотечные функции, если они доступны. ;)