Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Быстродействие циклов. Вопросы. (https://javascript.ru/forum/misc/32480-bystrodejjstvie-ciklov-voprosy.html)

Arconas 17.10.2012 16:35

Быстродействие циклов. Вопросы.
 
Добрый день.
Не так давно наткнулся на http://www.jstoolbox.com/2008/03/25/...zaciya-ciklov/, посвященную оптимизации циклов в JS. Стало интересно проверить на деле какой же из циклов реально быстрее.

В результате был написан такой код http://pastebin.com/9tfJVzbE, в котором Я использовал разную запись циклов (полная против краткой) и разный обход массива (i++ или i--). В первом варианте скрипта (http://pastebin.com/7iW79Za7) массив задавался в каждой функции. Сейчас Я его вынес в глобальную область и дал обычный вывод данных на страницу вместо консоли.

И вот какие результаты Я получил:
Полная запись с len - это for(var i= 0, len = tArray.length; i<len; i++)
FF 16
Код:

for полная запись. Перебор по возрастающей 36 ms
for полная запись с len. Перебор по возрастающей 32 ms
for полная запись. Перебор по убывающей 39 ms
for краткая запись. Перебор по убывающей 38 ms
while. Перебор по возрастающей 46 ms
while. Перебор по убывающей 42 ms
do. Перебор по убывающей 43 ms



Chrome 22
Код:

for полная запись. Перебор по возрастающей 31 ms
for полная запись с len. Перебор по возрастающей 33 ms
for полная запись. Перебор по убывающей 34 ms
for краткая запись. Перебор по убывающей 35 ms
while. Перебор по возрастающей 45 ms
while. Перебор по убывающей 41 ms
do. Перебор по убывающей 40 ms

IE 9
Код:

for полная запись. Перебор по возрастающей 113 ms
for полная запись с len. Перебор по возрастающей 83 ms
for полная запись. Перебор по убывающей 76 ms
for краткая запись. Перебор по убывающей 73 ms
while. Перебор по возрастающей 87 ms
while. Перебор по убывающей 66 ms
do. Перебор по убывающей 79 ms

И вот тут возникли вопросы:
  1. Почему краткая запись, которая вроде бы должна быть быстрой, не такая быстрая? Или в статье всё врут? Она довольно старая.
  2. Не закралась ли в код ошибка и правильно ли Я понял краткую запись?
  3. Почему запись с вычислением длинны массива в условии срабатывает быстрее обычной?
И, что самое интересное, в первом варианте, где массив задавался в каждой функции перебор i-- проходил быстрее, чем по i++.
В JS новичок =(

melky 17.10.2012 17:47

оптимизировать циклы вообще нет смысла. пишите так, как хочется.

оптимизировать нужно в первую очередь алгоритм.

прирост проиводительности из-за замены формы циклы почти не заметен. хотя ... "копейка рубль бережёт".


Цитата:

Сообщение от Arconas
Почему краткая запись, которая вроде бы должна быть быстрой, не такая быстрая?

краткость != скорость.
Цитата:

Сообщение от Arconas
Почему запись с вычислением длинны массива в условии срабатывает быстрее обычной?

оптимизации на уровне движка.

мерять лучше на jsperf.com ... там есть уже с десяток, наверное - если на с сотню - подобных тестов на скорость циклов.

trikadin 17.10.2012 18:13

Цитата:

Сообщение от melky
прирост проиводительности из-за замены формы циклы почти не заметен. хотя ... "копейка рубль бережёт".

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

Arconas 17.10.2012 21:03

Цитата:

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

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

А желание проверить скорость работы циклов вылилось, собственно, из задачи по перестановке элементов массива в обратном порядке. Там Я сравнивал метод с переменной, с дополнительным массивом и array.reverse(); Reverse, кстати оказался самым медленным во всех браузерах кроме IE. Оптимизация и производительность носили учебный характер. В настоящем приложении данных немного, чтобы их количество как-то повлияло на скорость.
Цитата:

Сообщение от melky (Сообщение 210838)
краткость != скорость.

Это тоже понятно. Не раз и не два, и даже не три натыкался на статьи по оптимизации скриптов и там почти всегда присутствовал совет убрать из цикла якобы не нужные условия. Любопытство снова взяло верх и Я решил попробовать сравнить. Результаты оказались не такими как Я ожидал и написал в личку Илье с вопросом почему так и где Я ошибся. Илья посоветовал перенести обсуждение на форум :(

Цитата:

Сообщение от melky (Сообщение 210838)
мерять лучше на jsperf.com ...

Чем он лучше, если там тот же самый код? :)

Цитата:

что нет смысла писать их как-то извращённо - предсказать, в каком конкретном случае скорость возрастёт, нереально)
Согласен. Так же нет смысла доверять советам из статей по оптимизации касательно циклов и длины имени переменной =) Но когда нечем заняться, а программировать хочется - пишу тесты из любопытства. Знаю, что глупо.

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

melky 17.10.2012 21:58

Цитата:

Сообщение от Arconas
На самом деле вопросы носили чисто учебный характер, так как разница в циклах практически не заметна в обычных условиях, но, как Вы правильно подметили, копейка рубль бережет. Опять же из теста видно, что запись с объявлением границы цикла в некоторых браузерах работает быстрее.

V8, как выяснилось (ссыль на хабр ниже), оптимизирует ещё и байткод, который получается на выходе компилятора - поэтому самый что ни на есть длинный и привычный цикл становится самым быстрым.

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

Хотя, Клиффорд, похоже, занимался этим ... гм, "ЭТИМ".

http://habrahabr.ru/post/154537/

Я, конечно, люблю полазить в дебрях V8 и двига FireFox (забыл, как его ...), но только в экстренных и неразрешимых случаях.
Цитата:

Сообщение от Arconas
Чем он лучше, если там тот же самый код?

Верно, одно и то же ... но там красивее и нагляднее :)

Цитата:

Сообщение от Arconas
В общем... особенности движков. Никакой мистики.

В этом же и мистика :)

Nekromancer 17.10.2012 22:53

melky,
SpiderMonkey.

Arconas,
у вас там замыкания спрошь и рядом, конечно будут результаты разные, тут уже нужно смотреть на то, как движки оптимизируют lookup и всё такое. сделайте всё отдельно и в одной функции на каждый тест, тогда можно говорить о результатах. И да, jsperf лучше, просто потому, что лучше. Там проверяется не только врея, но и другие нюансы, в которые я даже не углублялся, но можно почитать документацию.

Nekromancer 17.10.2012 22:55

Незаметил первый вариант:
Цитата:

В первом варианте скрипта (http://pastebin.com/7iW79Za7) массив задавался в каждой функции. Сейчас Я его вынес в глобальную область и дал обычный вывод данных на страницу вместо консоли.
В нём лучше сделанно.

melky 17.10.2012 23:15

Цитата:

Сообщение от Nekromancer
melky,
SpiderMonkey.

я его всё время путаю с SunSpider из-за похожести имён.

trikadin 17.10.2012 23:26

Цитата:

Сообщение от melky
я его всё время путаю с SunSpider из-за похожести имён.

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

Nekromancer 18.10.2012 00:39

trikadin,
Это от куда такая инфа то? Основной вроде SpiderMonkey. А IonMonkey и JugerMonkey это просто надможества, грубо говоря.


Часовой пояс GMT +3, время: 05:35.