Я узнал из книг, что вы должны написать для цикла, как это:
for(var i=0, len=arr.length; i < len; i++){
// blah blah
}
так что arr.length
не будет рассчитываться каждый раз.
Другие говорят, что компилятор сделает некоторую оптимизацию для этого, так что вы можете просто написать:
for(var i=0; i < arr.length; i++){
// blah blah
}
Я просто хочу знать, какой способ лучше всего применять на практике?
javascript
performance
loops
wong2
источник
источник
for ... of
цикл в этом конкурсе? Синтаксис кажется даже проще, чем цикл for без кэширования, и я хочу знать, стоит ли переходить на использование циклов for.Ответы:
После выполнения этого теста с большинством современных браузеров ...
http://jsben.ch/dyM52
В настоящее время самая быстрая форма цикла (и на мой взгляд самая синтаксически очевидная).
стандарт для цикла с кэшированием длины
Я бы сказал, что это определенно тот случай, когда я приветствую разработчиков движка JavaScript. Время выполнения должно быть оптимизировано для ясности , а не хитрости .
источник
++i
.for(var i=0, len=myArray.length; i<len; ++i)
проверьте jsperf.com/caching-array-length/84var
оператора. Как это написано,len
на самом деле ограничено, как вы предлагаете.Абсолютно быстрый способ перебрать массив javascript:
Смотрите http://blogs.oracle.com/greimer/entry/best_way_to_code_a для полного сравнения
источник
var
(иначеlen
становится глобальной переменной). Кроме того, см. Jsperf.com/loops для большего количества тестов цикла.По состоянию на июнь 2016 года проводятся некоторые тесты в последней версии Chrome (71% рынка браузеров в мае 2016 года и растет):
Я полагаю, что этот поток слишком стар, и программисты вводят в заблуждение, полагая, что им нужно кэшировать длину или использовать обратные обходы с уменьшением для достижения лучшей производительности, писать код, который менее читабелен и более подвержен ошибкам, чем простой простой цикл for. Поэтому я рекомендую:
Если ваше приложение выполняет итерации по большому количеству элементов или ваш код цикла находится внутри функции, которая часто используется, ответом является простой цикл for:
Если ваше приложение на самом деле не перебирает множество элементов или вам просто нужно делать небольшие итерации здесь и там, использование стандартного обратного вызова forEach или любой другой функции из вашей библиотеки JS может быть более понятным и менее подверженным ошибкам, поскольку Область видимости переменной индекса закрыта, и вам не нужно использовать скобки, получая прямой доступ к значению массива:
Если вам действительно нужно потерять несколько миллисекунд при итерации по миллиардам строк, а длина вашего массива не изменяется в процессе, вы можете рассмотреть кэширование длины в цикле for. Хотя я думаю, что сейчас это действительно не нужно:
источник
for(let i=0, j=array.length; i < j; i++)
, цикл for for for значительно ускорится. В нескольких тестах, которые я запускал, он выигрывал, в большинстве случаев он был в пределах погрешности или в обратном цикле.Если порядок не важен, я предпочитаю этот стиль:
Это кэширует длину и намного короче, чтобы написать. Но он будет перебирать массив в обратном порядке.
источник
i--
Возвращает число, и как только число становится0
условием,false
потому чтоBoolean(0) === false
.Это просто 2018 год, поэтому обновление может быть приятным ...
И я действительно должен не согласиться с принятым ответом . Это зависит от разных браузеров. некоторые делают
forEach
быстрее, некоторыеfor-loop
, а некоторыеwhile
вот тесты для всех методов http://jsben.ch/mW36eи так как вы можете увидеть много для цикла, как
for(a = 0; ... )
то стоит упомянуть, что без переменных 'var' будут определены глобально, и это может существенно повлиять на скорость, поэтому она будет медленной.Устройство Даффа работает быстрее в опере, но не в Firefox
источник
2014
While
вернулсяПросто подумай логично.
Посмотри на это
for
цикл имеет 3 параметраТеперь скажите мне, почему это должно быть быстрее, чем:
while
имеет только один параметрЯ был совершенно сбит с толку, когда Chrome 28 показал, что цикл for быстрее, чем какое-то время. Это должно быть бен какой-то
«Все используют цикл for, давайте сосредоточимся на этом при разработке для chrome».
Но теперь, в 2014 году, цикл while вернулся на хром. это в 2 раза быстрее, в других / старых браузерах это всегда было быстрее.
В последнее время я сделал несколько новых тестов. Теперь в реальном мире эти короткие коды ничего не стоят, и jsperf не может правильно выполнить цикл while, потому что он должен воссоздать array.length, что также требует времени.
Вы не можете получить фактическую скорость цикла while на jsperf.
вам нужно создать свою собственную функцию и проверить это с помощью
window.performance.now()
И да ... нет, пока цикл просто быстрее.
Например, у меня есть сцена холста, где мне нужно вычислить координаты и столкновения ... это делается между 10-200 микросекундами (не миллисекундами). для рендеринга всего требуется несколько миллисекунд. То же, что и в DOM.
НО
В
loop
некоторых случаях есть еще один суперэффективный способ использования for ... например, для копирования / клонирования массива.Обратите внимание на настройку параметров:
Сказал, что это подтверждает, что машины, как -
написав, что я думаю сделать его немного короче и удалить некоторые ненужные вещи, я написал этот в том же стиле:
Даже если он короче, похоже, что использование еще
i
одного раза все замедляет. Это на 1/5 медленнее, чем предыдущийfor
цикл иwhile
один.Примечание:
;
очень важно после того , как для looo без{}
Даже если я только что сказал вам, что jsperf не лучший способ протестировать скрипты ... я добавил эти 2 цикла здесь
http://jsperf.com/caching-array-length/40
А вот еще один ответ о производительности в JavaScript
https://stackoverflow.com/a/21353032/2450730
Этот ответ, чтобы показать эффективные способы написания JavaScript. Так что если вы не можете прочитать это, спросите, и вы получите ответ или прочитаете книгу о javascript http://www.ecma-international.org/ecma-262/5.1/
источник
for
был быстрее, чем когда-тоwhile
, и я однажды читал на crome-dev именно потому, что вы упомянули. Это было бы просто вопросом времени, прежде чемwhile
снова наверстать упущенное. С этого момента логика в первой части вашего ответа сохранится (еще раз, ура)! Однако современные реализации больше не следуют жестко за каждым шагом, заданным ecma (они оптимизируют). Так как теперь ваш движок больше не является самым заметным узким местом, теперь можно реально заметить промахи ЦП в обратных циклах !http://jsperf.com/caching-array-length/60
Последняя версия теста, которую я подготовил (используя более старую версию), показывает одну вещь.
Длина кеширования не так уж важна, но это не вредит.
Каждый первый запуск указанного выше теста (на только что открытой вкладке) дает наилучшие результаты для последних 4 фрагментов (3-го, 5-го, 7-го и 10-го в диаграммах) в Chrome, Opera и Firefox в моем 64-разрядном Debian Squeeze ( мое настольное оборудование) ). Последующие заезды дают совсем другой результат.
Выводы по производительности просты:
!==
вместо<
.shift()
массив также эффективны.ТЛ; др
В настоящее время (2011.10) шаблон ниже выглядит самым быстрым.
Имейте в виду, что кеширование
arr.length
здесь не является критическим, поэтому вы можете просто проверить его,i !== arr.length
и производительность не упадет, но вы получите более короткий код.PS: я знаю, что во фрагменте с
shift()
его результатом можно было бы использовать вместо доступа к 0-му элементу, но я почему-то упустил это из виду после повторного использования предыдущей ревизии (которая имела неправильные циклы while), и позже я не хотел терять уже полученные результаты.источник
«Лучший» как в чистом исполнении? или производительность И удобочитаемость?
Чистая производительность, «лучшая», - это использование кэша и префиксного оператора ++ (мои данные: http://jsperf.com/caching-array-length/189 ).
Я бы сказал, что цикл без кеша - лучший баланс времени выполнения и времени чтения программистом. Каждый программист, который начал с C / C ++ / Java, не будет тратить впустую мс, читая этот
источник
len
назван, всегда нужно сделать двойной цикл в первом цикле. Намерение второго цикла очевидно.** кешировать длину массива внутри цикла, несколько секунд времени будут исключены. Зависит от элементов в массиве, если в массиве больше элементов, есть существенная разница в отношении времени M *
**
**
**
**
источник
Это выглядит самым быстрым путем на сегодняшний день ...
Примите во внимание, что это будет использовать массив, съедая его и ничего не оставляя ...
источник
arr.shift();
вместо того,arr.pop()
чтобы избежать обратного массива.Это 2017 год .
Я сделал несколько тестов.
https://jsperf.com/fastest-way-to-iterate-through-an-array/
Похоже,
while
метод самый быстрый на Chrome.Похоже , левый декремента (
--i
) гораздо быстрее , чем другие (++i
,i--
,i++
) на Firefox.Этот подход постится в среднем. Но он перебирает массив в обратном порядке.
Если форвардный заказ важен, используйте этот подход.
источник
let
вы фактически сравниваете производительность создания области вместо производительности цикла. Использованиеlet i = 0, ii = array.length
в вашихfor
циклах создаст новую область видимости для этих переменных внутриfor
блока. Вашиwhile
примеры не создают новую область видимости для переменных внутриwhile
блока, и поэтому они быстрее. Если вы используетеvar
вместоlet
своих циклов for, вы увидите, что циклы for по-прежнему такие же быстрые, как и в 2017 году, но более удобочитаемые.var
иlet
имеют ту же производительность - stackoverflow.com/a/32345435/1785975while
быть быстрее в Chrome» точным. Это только при использованииlet
из-за проблем производительности этого ключевого слова в Chrome. При использованииvar
или с другими браузерами,for
иwhile
в значительной степени совпадают, иногдаfor
даже быстрее в зависимости от теста, и это более компактный и читаемый imho.Я всегда пишу в первом стиле.
Даже если компилятор достаточно умен, чтобы оптимизировать его для массивов, но все же он уместен, если мы используем DOMNodeList здесь или какой-то сложный объект с вычисленной длиной?
Я знаю, что вопрос о массивах, но я думаю, что это хорошая практика, чтобы написать все ваши циклы в одном стиле.
источник
i ++ быстрее, чем ++ i, --i и i--
Кроме того, вы можете сохранить последнюю строку, выполнив arr [i ++] в последний раз, когда вам нужен доступ к i (но это может быть трудно отладить).
Вы можете проверить это здесь (с другими циклами): http://jsperf.com/for-vs- whilepop/5
источник
++i
что быстрее ...По состоянию на сентябрь 2017 года эти тесты jsperf показывают, что следующий шаблон наиболее эффективен в Chrome 60:
Кто-нибудь может размножаться?
источник
Я попробовал несколько других способов перебора огромного массива и обнаружил, что вдвое уменьшить длину массива, а затем перебрать обе половинки в одном цикле быстрее. Это различие в производительности можно увидеть при обработке огромных массивов .
Некоторое сравнение производительности (с использованием timer.js) между кешированной длиной цикла for VS описанным выше методом.
http://jsfiddle.net/tejzpr/bbLgzxgo/
источник
Еще один тест на jsperf.com: http://jsperf.com/ while-reverse-vs-for-cached-length
Обратный цикл покажется самым быстрым. Единственная проблема в том, что while (--i) остановится на 0. Как я могу получить доступ к массиву [0] в моем цикле?
источник
while (i--)
то правдивостьi
будет проверена перед уменьшением, а не уменьшением, а затем проверяется на правдивость.Основной цикл while часто бывает самым быстрым. jsperf.com - отличная песочница для тестирования подобных концепций.
https://jsperf.com/fastest-array-loops-in-javascript/24
источник
Хотя цикл немного быстрее, чем для цикла.
Вместо этого используйте цикл while
источник
Самый быстрый подход является традиционным для цикла. Вот более полное сравнение производительности.
https://gists.cwidanage.com/2019/11/how-to-iterate-over-javascript-arrays.html
источник
Самое элегантное решение, которое я знаю, это использование карты.
источник
Попробуй это:
источник
Более быстрый способ создания цикла в массиве - использование фильтра. Метод filter () создает новый массив со всеми элементами, которые проходят тест, реализованный предоставленной функцией.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Исходя из моего опыта, я всегда предпочитаю фильтры, карты и т. Д.
источник
По состоянию на 2019 год WebWorker стал более популярным, для больших наборов данных мы можем использовать WebWorker для гораздо более быстрой обработки, полностью используя многоядерные процессоры.
У нас также есть Parallel.js, который значительно упрощает использование WebWorker для обработки данных.
источник