JavaScript: оптимизация цикла внутри цикла внутри цикла. Javascript оптимизация цикла
Оптимизация циклов в Javascript :: часть 2
Подготовил: Евгений Рыжков Дата публикации: 11.03.2012
Объединение циклов
Если несколько циклов работают, которые работают по одному и тому же интервалу, можно выполнить их объединение (jamming). Устраняем затраты связанные с выполнением дополнительного цикла. Код до:
for (var i = arrTest.length; i--;) { arrTest[i]=i; } for (var i = arrTest2.length; i--;) { arrTest2[i]=i*2; }Код после:
for (var i = arrTest.length; i--;) { arrTest[i]=i; arrTest2[i]=i*2; }Данная оптимизация кажется очевидной, но это только в простых ситуациях. В более сложных вараинтах приходиться хорошо подумать каким образом объединить циклы.
Вложение больших циклов в малые
Когда имеем дело с вложенными циклами стараемся сделать внешним циклом тот у кого итераций меньше. Код до:
Код после:
for(j=0; j<5; j++) { for(i=0; i<100; i++) { // какие-то действия } }В первом варианте общее число итераций равно 100 (число внешних итераций) + 5*100 (число внутренних) = 600. Для второго варианта — 5 (внешние итерации) + 5*100 (внутренние) = 505.
Размыкание цикла
Если во время выполнения цикла результат условия не изменяется, тогда цикл можно разомкнуть — поместить циклы в условие, а не условие в цикл. Код до:
for(i=0; i<100; i++) { if(something == anything) { // дейcтвие 1 } else { // действие 2 } }Код после:
if(something == anything) { for(i=0; i<100; i++) { // дейcтвие 1 } else { for(i=0; i<100; i++) { // действие 2 } }Про for-in
Забываем про эту конструкцию, если логика позволяет использовать обычный for: он в разы быстрее, чем for-in.
Материалы
По теме
Оптимизация циклов в Javascript :: часть 2 - The Media Image
Автор: Евгений Рыжков Дата публикации: 11.03.2012
Объединение циклов
Если несколько циклов работают, которые работают по одному и тому же интервалу, можно выполнить их объединение (jamming). Устраняем затраты связанные с выполнением дополнительного цикла. Код до:
for (var i = arrTest.length; i--;) { arrTest[i]=i; } for (var i = arrTest2.length; i--;) { arrTest2[i]=i*2; }Код после:
for (var i = arrTest.length; i--;) { arrTest[i]=i; arrTest2[i]=i*2; }Данная оптимизация кажется очевидной, но это только в простых ситуациях. В более сложных вараинтах приходиться хорошо подумать каким образом объединить циклы.
Вложение больших циклов в малые
Когда имеем дело с вложенными циклами стараемся сделать внешним циклом тот у кого итераций меньше. Код до:
for(i=0; i<100; i++) { for(j=0; j<5; j++) { // какие-то действия } }Код после:
for(j=0; j<5; j++) { for(i=0; i<100; i++) { // какие-то действия } }Размыкание цикла
Если во время выполнения цикла результат условия не изменяется, тогда цикл можно разомкнуть — поместить циклы в условие, а не условие в цикл. Код до:
for(i=0; i<100; i++) { if(something == anything) { // дейcтвие 1 } else { // действие 2 } }Код после:
if(something == anything) { for(i=0; i<100; i++) { // дейcтвие 1 } else { for(i=0; i<100; i++) { // действие 2 } }Про for-in
Забываем про эту конструкцию, если логика позволяет использовать обычный for: он в разы быстрее, чем for-in.
Материалы
По теме
xiper.net
оптимизация цикла внутри цикла внутри цикла
Я работаю с API, и он возвращает данные мне в нечетном формате. Или это по крайней мере для меня. Данные - часы работы магазина, я хочу их сопоставить с тем, как они мне нужны в интерфейсе (приложение написано в Angular, использует два API, поэтому мне нужно заставить API работать с моей логикой Я не хочу, чтобы приспособиться к их формату)
Это формат данных, поступающие из API:
var operatingHoursArray = [ {Weds: true, End: "17:00", Start: "09:00"}, {Tue: true, End: "17:00", Start: "09:00"}, {Thur: true, End: "17:00", Start: "09:00"}, {Sun: false, End: "", Start: ""}, {Sat: true, End: "17:00", Start: "09:00"}, {Mon: true, End: "17:00", Start: "09:00"}, {Fri: true, End: "17:00", Start: "09:00"} ]Странная структура ИМО, я предпочел бы в дни недели быть объектами, затем открытые и закрытые часы, заключенные в них. Мое приложение (AngularJS) требует данных, чтобы быть в следующем формате:
var formattedHours = { Sunday: 'Closed', Monday: 'Closed', Tuesday: 'Closed', Wednesday: 'Closed', Thursday: 'Closed', Friday: 'Closed', Saturday: 'Closed' };времена значение по умолчанию «Закрыто», это код, я использую, чтобы соответствовать день недели с форматом я требую его в:
var daysOfWeek = [ { sform: 'Mon', lform: 'Monday' }, { sform: 'Tue', lform: 'Tuesday' }, { sform: 'Weds', lform: 'Wednesday' }, { sform: 'Thur', lform: 'Thursday' }, { sform: 'Fri', lform: 'Friday' }, { sform: 'Sat', lform: 'Saturday' }, { sform: 'Sun', lform: 'Sunday' } ]; // Loop through the operating hours for the dealer for (var i = operatingHoursArray.length - 1; i >= 0; i--) { // Loop through the property names for each day, getting the first property name (the day of week) for (property in operatingHoursArray[i]) { // Loop through the days of the week for (var v = daysOfWeek.length - 1; v >= 0; v--) { // If the day of the week (array) matches the property name, get the details if(daysOfWeek[v].sform == property && operatingHoursArray[i][property] === true) { formattedHours[daysOfWeek[v].lform] = operatingHoursArray[i].Start + ' - ' + operatingHoursArray[i].End; } }; break; // Forces loop to stop after first property } };stackoverrun.com
Оптимизация циклов. JavaScript | junior script university
Оптимизируем конструкцию цикла for. При применении некоторых действий можно ускорить вычисления обычной конструкции for. Эта оптимизация оправдана только при работе с большими объемами данных.
// обычный цикл for (var i = 0; i < myarray.length; i++) { // любые действия с myarray[i] } // оптимизация 1 - кэшируем длину массива в переменную max. // это позволяет не обращаться каждый раз к массиву for (var i = 0, max = myarray.length; i < max; i++) { // любые действия с myarray[i] } // оптимизация 2 - выносим переменные за пределы конструкции. // NOTE: Усложняет перенос и рефакторинг кода. И как правило стремимся к тому, // что бы не плодить глобальные переменные var i = 0, max, myarray = []; for (i = 0, max = myarray.length; i < max; i++) { // любые действия с myarray[i] } // оптимизация 3 - заменяем `i++` на `i = i + 1` или `i += 1` var i = 0, max, myarray = []; for (i = 0, max = myarray.length; i < max; i += 1) { // любые действия с myarray[i] } // декремент вычисляется быстрее чем инкремент var i, myarray = []; for (i = myarray.length; i--;) { // любые действия с myarray[i] } // меняем на конструкцию while var myarray = [], i = myarray.length; while (i--) { // любые действия с myarray[i] }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// обычный цикл for (var i = 0; i < myarray.length; i++) { // любые действия с myarray[i] } // оптимизация 1 - кэшируем длину массива в переменную max. // это позволяет не обращаться каждый раз к массиву for (var i = 0, max = myarray.length; i < max; i++) { // любые действия с myarray[i] }
// оптимизация 2 - выносим переменные за пределы конструкции. // NOTE: Усложняет перенос и рефакторинг кода. И как правило стремимся к тому, // что бы не плодить глобальные переменные var i = 0, max, myarray = []; for (i = 0, max = myarray.length; i < max; i++) { // любые действия с myarray[i] }
// оптимизация 3 - заменяем `i++` на `i = i + 1` или `i += 1` var i = 0, max, myarray = []; for (i = 0, max = myarray.length; i < max; i += 1) { // любые действия с myarray[i] }
// декремент вычисляется быстрее чем инкремент var i, myarray = []; for (i = myarray.length; i--;) { // любые действия с myarray[i] }
// меняем на конструкцию while var myarray = [], i = myarray.length; while (i--) { // любые действия с myarray[i] } |
Так же ускорить процесс можно вычисляя некоторое количество действий внутри цикла.
var val = 0; for(var i = 0; i < 10000; i++){ val += 1; val += 1; val += 1; val += 1; val += 1; }
var val = 0; for(var i = 0; i < 10000; i++){ val += 1; val += 1; val += 1; val += 1; val += 1; } |
Но такие оптимизации ощущаются только на очень больших объемах данных. Поэтому как правило не используются.
junior-script-university.esy.es
optimization - Оптимизация цикла JavaScript делает его медленнее
Начнем с того, что я не вижу причин, почему второй должен быть намного быстрее первого. Разница между сравнением с нулем и сравнением с другим числом - это то, что может повлиять на чрезвычайно сложные циклы в скомпилированном коде, но даже там, вероятно, большую часть времени предпочитает культ груза (читай Ричарда Феймана Cargo Cult Science, t получить ссылку, если ничего более хорошо читать, есть также несколько раз, когда аналогичные тенденции копировать что-то, что хорошо работало один раз, в случае, когда нет никаких оснований полагать, что это поможет, в программировании).
Я видел, как следующее было медленнее:
for (i = 0; i < myarray.length; i++) { // do something with myarray[i] }Но я также мог видеть, что это не медленнее, если двигатель сделал оптимизацию проверки длины для вас, или реализация была такой, что проверка длины и проверка переменной в любом случае была эквивалентной стоимостью.
Я мог бы увидеть либо это, либо первый пример кода, который вы даете, или, возможно, и то, и другое, что-то, что оптимизирует данный сценарий-движок - это, в конце концов, очень распространенная идиома в js и по своей сути включает в себя цикл, поэтому было бы разумным чтобы попытаться определить и оптимизировать механизм сценариев.
Тем не менее, помимо таких догадок, мы не можем ничего сказать об этом за пределами "потому что один работает лучше в этом движке, чем другой, поэтому", не доходя до уровня ниже javascript и рассматривая реализацию движка. Ваши результаты приведут к тому, что ответ не будет одинаковым с каждым движком (в конце концов, один больше соответствовал тому, что вы ожидали).
Теперь стоит отметить, что в каждом случае результаты все равно близки друг к другу. Если вы обнаружили только один или два браузера, которые в настоящее время достаточно популярны, когда изменение действительно оптимизировалось, оно все равно может стоить того.
Если вас интересует, стоило ли это когда-либо или было просто предположение, что вы можете попытаться получить копию Netscape 2 (первый браузер javascript когда-либо, в конце концов) и запустить некоторый код для проверки подхода в теме.
Edit: Если вы попробуете этот эксперимент, другой должен попытаться преднамеренно багги-циклы, которые превышают границы массива одним. Одна из возможных оптимизаций для движка заключается в том, чтобы понять, что вы идете по массиву, и проверяйте один раз, где вы закончите для выхода из диапазона. если это так, у вас могут быть разные результаты, если вы в конечном итоге ошибетесь.
qaru.site
performance - JavaScript: оптимизация цикла внутри цикла внутри цикла
Я работаю с API, и он плюет на меня обратно в нечетном формате. Или это по крайней мере для меня. Данные - часы работы магазина, я хочу их сопоставить с тем, как они мне нужны в интерфейсе (приложение написано в Angular, использует два API, поэтому мне нужно заставить API работать с моей логикой, Я не хочу адаптироваться к их формату)
Это формат данных, поступающих из API:
var operatingHoursArray = [ {Weds: true, End: "17:00", Start: "09:00"}, {Tue: true, End: "17:00", Start: "09:00"}, {Thur: true, End: "17:00", Start: "09:00"}, {Sun: false, End: "", Start: ""}, {Sat: true, End: "17:00", Start: "09:00"}, {Mon: true, End: "17:00", Start: "09:00"}, {Fri: true, End: "17:00", Start: "09:00"} ]Нечетная структура ИМО, я бы предпочел, чтобы дни недели были объектами, затем открытые и закрытые часы, заключенные в них. Мое приложение (AngularJS) требует, чтобы данные были в следующем формате:
var formattedHours = { Sunday: 'Closed', Monday: 'Closed', Tuesday: 'Closed', Wednesday: 'Closed', Thursday: 'Closed', Friday: 'Closed', Saturday: 'Closed' };Times по умолчанию имеет значение "Закрыто", это код, который я использую, чтобы сопоставить день недели с форматом, в котором я нуждаюсь:
var daysOfWeek = [ { sform: 'Mon', lform: 'Monday' }, { sform: 'Tue', lform: 'Tuesday' }, { sform: 'Weds', lform: 'Wednesday' }, { sform: 'Thur', lform: 'Thursday' }, { sform: 'Fri', lform: 'Friday' }, { sform: 'Sat', lform: 'Saturday' }, { sform: 'Sun', lform: 'Sunday' } ]; // Loop through the operating hours for the dealer for (var i = operatingHoursArray.length - 1; i >= 0; i--) { // Loop through the property names for each day, getting the first property name (the day of week) for (property in operatingHoursArray[i]) { // Loop through the days of the week for (var v = daysOfWeek.length - 1; v >= 0; v--) { // If the day of the week (array) matches the property name, get the details if(daysOfWeek[v].sform == property && operatingHoursArray[i][property] === true) { formattedHours[daysOfWeek[v].lform] = operatingHoursArray[i].Start + ' - ' + operatingHoursArray[i].End; } }; break; // Forces loop to stop after first property } };Это становится действительно неприятным, очень быстрым, но с моими знаниями (уровень noob) я не уверен, как сделать это более эффективным. Он работает для того, что мне нужно, но есть ли лучший способ кодировать это? В настоящее время он должен работать 49 раз, чтобы проверять каждый день недели. Кроме того, некоторые магазины не предоставляют 7 дней в часах, вместо этого предоставляют только часы, в которые они открыты. Я не могу изменить структуру formattedHours потому что другой API зависит от той же структуры.
qaru.site