【js】for、forEach、map數組遍歷性能比較
- 2020 年 3 月 17 日
- 筆記
原文鏈接:https://blog.csdn.net/qq24357165/article/details/82748976
先上結果:遍歷時間上 for循環遍歷 < for…of遍歷 < forEach遍歷 < for…in遍歷 < map遍歷。
背景
常用的數組遍歷方式有很多,如最經典的for循環
for (var i = 0; i < arr.length; i++) {}
再者有了for…in
for (var i in arr) {}
forEach
arr.forEach(function (i) {});
map
arr.map(function (i) {});
然後ES6有了更為方便的for…of
for (let i of arr) {}
此篇不考慮作用差異,僅對這些方式的性能做一次比較。
註:filter、every、some跟forEach/map相近,不常用所以本次不加入比較。
1.對比方案
本次採用最直觀的方式進行對比:通過對高數量級數組的遍歷時間進行比較。
1.1 數組arr:
let arr = []; for (let i = 0; i < 10000000; i++) { arr[i] = i; } console.log(arr); // [0, 1, 2, 3, ... , 9999999]
1.2 對比函數:
function getAverageTime (cb) { let _start = +new Date(); for (let k = 0; k < 20; k++) { cb(); // 遍歷函數 } return (+new Date() - _start) / 20 + 'ms' }
其中cb為遍歷函數。我們通過20次求平均值的方式來推算遍歷的時間,以此作為比較依據。
2.比較
1.1 經典的for循環遍歷
getAverageTime(function () { for (let i = 0; i < arr.length; i++) { let item = arr[i]; // ... } })
結果:6.3ms

1.2 for…in遍歷
getAverageTime(function () { for (let i in arr) { let item = arr[i]; // ... } })
結果:1539.45ms

1.3 forEach遍歷
getAverageTime(function () { arr.forEach(item => {}) });
結果:190.75ms

1.4 map遍歷
getAverageTime(function () { arr.map(item => {}) });
結果:2014.65ms

1.5 for…of遍歷
getAverageTime(function () { for (let item of arr) { // ... } });
結果:129.5ms

*babel轉ES5後遍歷
for…of是ES6語法,所以日常頁面中基本會babel轉換,所以需要測試一下轉換後的遍歷
getAverageTime(function () { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = arr[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { //... var item = _step.value; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } });
結果:105.9ms

(是不是感覺for…of經過Babel轉換後的程式碼很詭異,有興趣可以去了解下Symbol對象,其實Symbol對象也是ES6所新加的,只是兼容比for…of好些,要兼容低版本手機的話了解一下es-symbol)
3 結果分析
通過對比可知,遍歷時間
for循環遍歷 < for...of遍歷 < forEach遍歷 < for...in遍歷 < map遍歷
3.1 *為何for… in會慢?
因為for … in語法是第一個能夠迭代對象鍵的JavaScript語句,循環對象鍵({})與在數組([])上進行循環不同,引擎會執行一些額外的工作來跟蹤已經迭代的屬性。
因此可以大致可以得出以下幾點:
- 數據量大時,遍歷性能的差距尤為明顯;
- for系遍歷總體性能好於forEach、map等數組方法
- 你大爺畢竟是你大爺,性能最佳的還是經典的for循環遍歷
- forEach性能優於map
- for…of要兼容低版本設備的話還是算了
遍歷的性能可以作為以後開發的參考,畢竟數據量不大的時候差異可忽略不計,更多的可以根據實際作用來考慮遍歷方式,比方說for系遍歷可以break中途退出而forEach/map不行。
版權聲明:本文為CSDN部落客「MichealWayne」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/qq24357165/article/details/82748976