Современный JS предоставляет множество способов перебора массива. Но какой из них является наиболее эффективным по скорости?
Чтобы ответить на этот вопрос, мы проведем тесты, перебирая массивы разной длины и вызывая для каждого элемента метод toString()
.
Рассмотрим основные способы перебора: for
, for(reverse)
, while
, do..while
, for..in
, for..of
, for..each
.
Важно! Точность результата
console.time()
сильно зависит от конфигурации вашей системы.
Для начала протестируем скорость каждого способа на массиве из 1000 элементов.
const iterations = 1000;
const array = new Array(iterations).fill(0);
console.log("Длина массива", + array.length);
//for
console.time("for");
for (let i = 0; i < array.length; i++) {
array[i].toString();
}
console.timeEnd("for");
//forReverse
console.time("for(reverse)");
for (let i = array.length - 1; i >= 0; i--) {
array[i].toString();
}
console.timeEnd("for(reverse)");
//while
console.time("while");
let i = 0;
while (i < array.length) {
array[i].toString();
i++;
}
console.timeEnd("while");
//do...while
console.time("do...while");
let j = 0;
do {
array[j].toString();
j++;
} while (j < array.length);
console.timeEnd("do...while");
//for...in
console.time("for...in");
for (let k in array) {
k.toString();
}
console.timeEnd("for...in");
//for...of
console.time("for...of");
for (let l of array) {
l.toString();
}
console.timeEnd("for...of");
//for...each
console.time("for...each");
array.forEach((el) => {
el.toString();
});
console.timeEnd("for...each");
![](https://habrastorage.org/getpro/habr/upload_files/64e/d98/0a4/64ed980a41c55c651df64a948af8145b.png)
Результат интересный: цикл for
значительно уступает другим способам. Но сохранится ли эта тенденция при большей выборке? Чтобы получить более ясную картину, увеличим количество итераций.
![](https://habrastorage.org/getpro/habr/upload_files/574/eb7/4aa/574eb74aaf461cb81cb19532f0054666.png)
![](https://habrastorage.org/getpro/habr/upload_files/e3f/0b8/b97/e3f0b8b97c316a389eb88f6c75a8ecbb.png)
![](https://habrastorage.org/getpro/habr/upload_files/10a/25a/d33/10a25ad33f2218fed91d57701e47d74d.png)
![](https://habrastorage.org/getpro/habr/upload_files/577/2f2/ec3/5772f2ec34d4ad3e58602d7aa7bd0dab.png)
После проведения тестирования мы не можем однозначно назвать самый быстрый способ перебора массива, так как победители меняются в зависимости от размера массива. Однако, стандартный for
цикл, for(reverse)
цикл, while
цикл и do...while
цикл будут наилучшим выбором, так как они работают практически одинаково быстро в большинстве случаев.
Рекомендуется использовать префиксные операторы (--i, ++i) вместо постфиксных (i--, i++), так как постфиксные операторы требуют создания временной копии переменной, что занимает дополнительное время на вычисление значения выражения. В свою очередь, префиксный оператор изменяет значение переменной непосредственно в момент выполнения операции, без создания временной копии, что делает его более эффективным и быстрым.
Также для улучшения скорости необходимо кэшировать длину массива заранее.
const arrayLength = array.length;
for (let i = 0; i < arrayLength; i++) {
array[i].toString();
}
Если вас волнует производительность, то следуйте вышеуказанным рекомендациям, но, как всегда, оптимизируйте производительность только тогда, когда это необходимо, так как читаемость и удобство обслуживания часто более важны.
Комментарии (5)
andreymal
25.09.2023 11:11В какой среде это всё хоть? Когда я пытался колхозно измерять производительность циклов в Chrome и Firefox, то получал почти противоположные результаты
Aquahawk
Ну как так. Где прогрев, где вычисление отклонения? Поменяйте тесты местами и очень удивитесь. Поставьте быстрейший do...while в начало и получите что он станет почти самым медленным. Про кеширование длины и префискные постфиксные формы вообще молчу. Скройте статью и не позорьтесь, а сами сходите посмотрите видосы из этого плейлиста, он конечно старенький, но ничуть актуальности не утратил https://www.youtube.com/playlist?list=PLarlUwZRmTK6ptk3MtivPgcMikbYSKFnO и начните с этого
aleksandy
Зачем? Статья опубликована, галочка преподавателем поставлена, а содержание... да кого вообще волнуют подобные мелочи?