Давайте рассмотрим, какой способ перебора элементов будет максимально быстрым в 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 элементов, то в результате применения оптимизированных приемов будет заметен значительный прирост производительности.