Тесты производительности для распространенных методов массива JavaScript
20 марта 2022 г.Этот пост в блоге посвящен сравнению времени выполнения наиболее часто используемых способов перебора массива в JavaScript, чтобы увидеть, какой из них наиболее эффективен.
Тесты
Идея очень проста. Я сравнил время выполнения пяти очень распространенных способов (map
, forEach
, for
, while
, do while
) перебора массива с использованием массива из 100 значений и другого массива из 10 миллионов значений. . Используемый код был запущен в среде выполнения Node.js версии 16.14.0 на ноутбуке с Ubuntu 20.
Тестирование метода .map()
Вот код, используемый для массива из 100 значений
```javascript
константный размер массива = 100;
const arrayToTest = Массив (размер массива)
.заполнить(0)
.map((_, я) => я);
// небольшой код для разогрева используемого процесса
for (пусть индекс = 0; индекс < arrayToTest; индекс++) {
индекс * индекс + Math.sqrt (элемент);
console.time("карта");
arrayToTest.map((элемент, индекс) => {
return (arrayToTest[index] = элемент * элемент + Math.sqrt (элемент));
console.timeEnd("карта");
Вот результат, который я получил из приведенного выше кода:
карта: 0,150 мс
Для массива из 10 миллионов значений я использовал тот же код, что и выше, просто заменив константу arraySize
на 10000000. Вот результат, который я получил:
карта: 1865,563 мс
Тестирование метода .forEach()
Вот код, используемый для массива из 100 значений
```javascript
константный размер массива = 100;
const arrayToTest = Массив (размер массива)
.заполнить(0)
.map((_, я) => я);
// небольшой код для разогрева используемого процесса
for (пусть индекс = 0; индекс < arrayToTest; индекс++) {
индекс * индекс + Math.sqrt (элемент);
console.time("для каждого");
arrayToTest.forEach((элемент, индекс) => {
return (arrayToTest[index] = элемент * элемент + Math.sqrt (элемент));
console.timeEnd ("для каждого");
Вот результат, который я получил из приведенного выше кода:
для каждого: 0,137 мс
Для массива из 10 миллионов значений я использовал тот же код, что и выше, просто заменив константу arraySize
на 10000000. Вот результат, который я получил:
для каждого: 1201,149 мс
Проверка цикла for
Вот код, используемый для массива из 100 значений
```javascript
константный размер массива = 100;
const arrayToTest = Массив (размер массива)
.заполнить(0)
.map((_, я) => я);
// небольшой код для разогрева используемого процесса
for (пусть индекс = 0; индекс < arrayToTest; индекс++) {
индекс * индекс + Math.sqrt (элемент);
console.time("для");
for (пусть я = 0; я < arrayToTest.length; я ++) {
arrayToTest[i] = arrayToTest[i] * arrayToTest[i] + Math.sqrt(arrayToTest[i]);
console.timeEnd ("для");
Вот результат, который я получил из приведенного выше кода:
для: 0,127 мс
Для массива из 10 миллионов значений я использовал тот же код, что и выше, просто заменив константу arraySize
на 10000000. Вот результат, который я получил:
для: 109,778 мс
Проверка цикла while
Вот код, используемый для массива из 100 значений
```javascript
константный размер массива = 100;
const arrayToTest = Массив (размер массива)
.заполнить(0)
.map((_, я) => я);
// небольшой код для разогрева используемого процесса
for (пусть индекс = 0; индекс < arrayToTest; индекс++) {
индекс * индекс + Math.sqrt (элемент);
console.time("пока");
пусть я = 0;
в то время как (я < arrayToTest.length) {
массивТест[я] =
arrayToTest[i] * arrayToTest[i] + Math.sqrt(arrayToTest[i]);
я++;
console.timeEnd("пока");
Вот результат, который я получил из приведенного выше кода:
пока: 0,294 мс
Для массива из 10 миллионов значений я использовал тот же код, что и выше, просто заменив константу arraySize
на 10000000. Вот результат, который я получил:
пока: 108,698 мс
Проверка цикла do…while
Вот код, используемый для массива из 100 значений
```javascript
константный размер массива = 100;
const arrayToTest = Массив (размер массива)
.заполнить(0)
.map((_, я) => я);
// небольшой код для разогрева используемого процесса
for (пусть индекс = 0; индекс < arrayToTest; индекс++) {
индекс * индекс + Math.sqrt (элемент);
console.time("делать пока");
пусть я = 0;
делать {
arrayToTest[i] = arrayToTest[i] * arrayToTest[i] + Math.sqrt(arrayToTest[i]);
я++;
} while (i < arrayToTest.length);
console.timeEnd("делать пока");
Вот результат, который я получил из приведенного выше кода:
делать пока: 0,118 мс
Для массива из 10 миллионов значений я использовал тот же код, что и выше, просто заменив константу arraySize
на 10000000. Вот результат, который я получил:
делать пока: 124,894 мс
Резюме
Для массива со 100 значениями вот результаты, которые я получил
карта: 0,150 мс
для каждого: 0,137 мс
для: 0,127 мс
пока: 0,120 мс
делать пока: 0,118 мс
Для второго массива с 10 миллионами значений вот результаты, которые я получил
карта: 1865,563 мс
для каждого: 1201,149 мс
для: 109,778 мс
пока: 145,869 мс
делать пока: 124,894 мс
- В небольших массивах работа по оптимизации, выполняемая движком V8 при компиляции нашего кода JavaScript, достаточно хороша, а время выполнения протестированных выше методов очень близко.
- В больших массивах
map()
иforEach()
занимают гораздо больше времени (более чем в одиннадцать раз, как показано в этом примере), чем другие методы. Одним из факторов, вызывающих это дополнительное время, является вызов функций обратного вызова, которые потребляют больше памяти и, следовательно, увеличивают затраты производительности в больших массивах.for
while
илиdo while
имеют очень близкое время выполнения в больших массивах, и трудно сказать, по крайней мере, из приведенных выше примеров, что один из них радикально быстрее, чем другие в больших массивах. В этом смысле необходимы дополнительные тесты, чтобы определить, какой метод является наиболее эффективным.
Заключение
Всякий раз, когда нам нужно написать цикл, важно подумать, какое решение работает лучше всего. В относительно небольших массивах работа по оптимизации, выполняемая движком V8, достаточно хороша. Однако при обработке большого объема данных стоимость производительности может быть важной, если мы не выберем наиболее эффективное решение, а время работы может быть в одиннадцать раз больше в некоторых случаях, как показано в результатах выше.
Производительность — не единственное, что имеет значение. Читабельность и ремонтопригодность кода также очень важны при написании кода на любом языке программирования. Вы можете проверить [предыдущую статью] (https://hackernoon.com/the-clean-code-book-for-javascript-developers-a-quick-summary-m82b373s). Я писал о том, как писать чистый код для разработчиков JavaScript. .
Если этот пост был полезен для вас, пожалуйста, не стесняйтесь поделиться им. Вы также можете подписаться на мой аккаунт в Твиттере, если хотите видеть больше контента, связанного с веб-программированием.
Оригинал