Тесты производительности для распространенных методов массива JavaScript

Тесты производительности для распространенных методов массива 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. .


Если этот пост был полезен для вас, пожалуйста, не стесняйтесь поделиться им. Вы также можете подписаться на мой аккаунт в Твиттере, если хотите видеть больше контента, связанного с веб-программированием.





Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE