torbasow (torbasow) wrote,
torbasow
torbasow

Categories:
  • Mood:
  • Music:

Javascript: прямой цикл, обратный цикл…

Прочитал, что цикл вида for(var j=testedArr.length; j--;){…} выполняется быстрее цикла вида for(var j=0; j<testedArr.length; j++){…} «для большинства реализаций Javascript». Собственно, это хорошо известно. Сейчас я просто решил проверить.

Так вот, это действительно верно для всех браузеров, а в особенности — IE 8 (оный, между прочим, в своей обычной хамской манере вынудил меня править реестр), кроме Google Chrome. Последний выполняет обратный цикл даже чуть медленнее, нежели прямой. Дюже странно сие, а на порядок большее общее время выполнения тестовых скриптов, нежели у остальных браузеров (кроме, конечно, IE), и тем паче.

Погружён в раздумья: грешит ли обратный цикл против семантики?

P. S. Привожу результаты испытаний. На входе кода имелся массив testedArr, заполненный 10 млн случайных чисел. В цикле производилось одно и то же действие: testedArr[j]+=1;; различался только способ организации цикла. После цикла выводилось прошедшее время в миллисекундах. Данные пяти последовательных испытаний усреднялись и округлялись.

Средняя продолжительность выполнения тестового цикла, мс
Firefox 2.0Internet Explorer 8Opera 9.64Google Chrome 5.0.375Firefox 3.6.3Opera 10.53Safari 4.0.5
for(var j=testedArr.length; j--;){…}20 03110 55072404881620420362
var j=testedArr.length; while(j--){…}20 04410 703720049636184729368
for(var j=testedArr.length; j; j--){…}22 02811 62584414961633414339
for(var j=0, len=testedArr.length; j<len; j++){…}24 37513 16694814864664420358
for(var j=0; j<testedArr.length; j++){…}25 81215 22510 6504959670519372

Выводы:

  1. Принимая во внимание более чем тридцатикратное превосходство современного «Файерфокса» над вторым, отставание в клонировании и сертификации КГОД для архитектуры «толстого клиента» — это просто ужас какой-то! Ведь актуальная версия КГОД 2 — это вообще Firefox 1.5.

  2. Новая «Опера» почему-то дико не любит while. Для остальных браузеров первые два вариант практически эквивалентны. С точки зрения семантики у обоих есть свои плюсы: while обозначает в явном виде терминальное условие, а for вбирает в себя определение нужной только в цикле переменной-счётчика. С этой точки зрения идеально было бы писать что-то вроде: for(var j=testedArr.length) while(j--){…}.

  3. Разделение декремента и терминального условия приводит к некоторому замедлению во всех браузерах, кроме новой «Оперы» и «Сафари».

  4. Прямой цикл во всех браузерах оптимизируется выносом длины массива в переменную. Очевидный минус: лишняя переменная.

  5. Однако, если мы всё же вынесем длину массива в переменную, обратный цикл окажется быстрее прямого только в IE и Firefox (да ещё в старой «Опере»). В остальных браузерах выгода разве что в отсутствии лишней переменной.

Я не стал испытывать напрашивающийся и изящный с виду for(var j in testedArr){…}, ибо его производительность падает с увеличением размера массива экспоненциально, а при десяти миллионах элементов многократно проигрывает всем другим вариантам.

Tags: chrome, ecmascript, ie, программирование
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 19 comments