专栏首页前端技术江湖【js】for、forEach、map数组遍历性能比较

【js】for、forEach、map数组遍历性能比较

原文链接: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

本文分享自微信公众号 - 前端技术江湖(bigerfe),作者:Micheal_Wayne

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【扒一扒】深入理解 ES6 Iterator

    本文主要来说下ES6的Iterator,目的在于理解它的概念、作用、以及现有的应用,最后学以致用。

    zz_jesse
  • React Router5 感性认知

    本文主要是了解下 react-router 新版本一些理念,为我们以后的开发注入一些感性认知。

    zz_jesse
  • 我和京东的不解之缘,和物流的始末....

    上一次已经说完和jd商城的事儿,其实最先开始的是jd物流。物流面比商城更早,但是商城是先进行完的。

    zz_jesse
  • LeetCode 40.最小的k个数

    输入整数数组 arr ,找出其中最小的 k 个数。例如,输入 4、5、1、6、2、7、3、8 这 8 个数字,则最小的 4 个数字是 1、2、3、4

    村雨遥
  • 2 :基本语法

    六月的雨
  • 冒泡排序

    用户6404053
  • 5个数求最值

    输入输入只有一组测试数据,为五个不大于1万的正整数输出输出两个数,第一个为这五个数中的最小值,第二个为这五个数中的最大值,两个数字以空格格开。样例输入

    书童小二
  • js排序算法

    山河木马
  • JavaScript实现冒泡排序

    对数组进行 冒泡排序 算是比较简单的,冒泡排序也是容易理解的一种排序算法了,在面试的时候,很可能就会问到。

    FEWY
  • 寻找数组中第二小的元素

    一觉睡到小时候

扫码关注云+社区

领取腾讯云代金券