Давайте рассмотрим, какой способ перебора элементов будет максимально быстрым в JavaScript. У нас есть несколько возможностей для реализации цикла, ниже приведен полный вариант кода для тестирования.
<!-- набор элементов для результатов тестирования --> <p id="test1"></p> <p id="test2"></p> <p id="test3"></p> <p id="test4"></p> <p id="test5"></p> <p id="test6"></p> <script type="text/javascript"> // выбираем все элементы из DOM-дерева var items = document.getElementsByTagName("*");// кэшируем текущий размер DOM-дерева var length = items.length; // запоминаем текущий момент времени var time = new Date().getTime(); // запускаем первый тест, обычный перебор элементов массива,// запускается 10000 раз for (varj=0; j<10000; j++) { for (var i=0; i<items.length; i++) { var item = items[i]; } } // выводим результат в подготовленный выше контейнер document.getElementById('test1').innerHTML = "Простойцикл: " + (new Date().getTime() - time); time = new Date().getTime(); // кэшируем размер массива for (var j=0; j<10000; j++) { for (var i=0; i<length; i++) { var item = items[i]; } } document.getElementById('test2').innerHTML = "Простойцикл (скэшированием): " + (new Date().getTime() - time); time = new Date().getTime(); // встроенный for-in итератор для объекта массива for (var j=0; j<10000; j++) { for (var i in items) { var item = items[i]; } } document.getElementById('test3').innerHTML = "Простойчерез for-in: " + (new Date().getTime() - time); time = newDate().getTime(); // обратный перебор элементов массива for (var j=0; j<10000; j++) { for (var i = length - 1; i >= 0; i--) { var item = items[i]; } } document.getElementById('test4').innerHTML = "Обратный: " + (new Date().getTime() - time); time = new Date().getTime(); // итератор do-while for (var j=0; j<10000; j++) { var i = 0; do { var item = items[i]; i++; } while (i < length) } document.getElementById('test5').innerHTML = "do-while: " + (new Date().getTime() - time); time = new Date().getTime(); // обратный while (самый быстрый) for (var j=0; j<10000; j++) { var i = length - 1; while (--i) { var item = items[i]; } } document.getElementById('test6').innerHTML = "Обратный while: " + (new Date().getTime() - time); </script>
В результате мы получим примерно следующую таблицу (табл. 7.3).
Браузер | Обычный | С кэшем | for-in | Обратный | do-while | Обратный while |
---|---|---|---|---|---|---|
Firefox 3.0.3 | 714 | 657 | 835 | 280 | 297 | 217 |
Safari 3.1.2 | 141 | 140 | 157 | 125 | 125 | 93 |
Opera 9.61 | 188 | 125 | 765 | 94 | 94 | 78 |
IE 6 | 1281 | 1219 | 1094 | 468 | 500 | 360 |
IE 7 | 1391 | 1297 | 1250 | 515 | 532 | 406 |
IE 8b2 | 954 | 906 | 922 | 406 | 422 | 328 |
Chrome 0.2 | 288 | 246 | 332 | 117 | 114 | 95 |
Таблица 7.3. Различные варианты перебора массива, результаты в миллисекундах
В общем случае применение обратного while
для перебора цикла в 2–3 раза быстрее всех остальных вариантов. Если веб-приложение оперирует массивами порядка 1000 элементов, то в результате применения оптимизированных приемов будет заметен значительный прирост производительности.