前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >js数组循环效率讨论

js数组循环效率讨论

作者头像
腾讯IVWEB团队
发布2020-06-24 11:03:53
4.1K0
发布2020-06-24 11:03:53
举报
文章被收录于专栏:腾讯IVWEB团队的专栏

前言

今天做项目时,遇到了一个很大很大的数组,并且需要在数组中去实现模糊搜索。因为现在数据时代,数据繁多,平时进行数据可视化开发时,经常遇到针对数组的排序、遍历、搜索、增删、去重等等操作。所以在这里就想着写一篇有关js数组循环的讨论。(以后应该会补充有关对象迭代的问题)

js循环方法

其实现在js循环方法已经有许多,从最初的for、while到后来es6中的foreach、for in、for of、map、filter,以及还有不常用的reduce、everysome方法。其实不同的方法使用场景不同,比如for in遍历键值,for of遍历值(其实虽然for in经常用于遍历对象,但下文还是主要针对于数组比较),所以其实不能够盲目去比较。但是当一个场景,你找不到最适用的方法,其实就可以从本文找找思路,本文也就最简单的循环进行遍历的效率与性能的测试,希望能得到一个适用普通场景最佳循环方法的结论。

for循环

代码语言:javascript
复制
var arr = [1, 2, 3, ..., 9999999] // 这里创建数组的步骤就省略
// method 1
for(let i = 0; i < arr.length; i++) { console.log(arr[i]) }
// method 2
for(let i = 0, len = arr.length; i < len; i++) { console.log(arr[i]) }
// method 3
for(let i = 0, arrIndex; arrIndex = arr[i]; i++) { console.log(arrIndex) }

对于上面三种方法,前两种比较常见,对于方法一和方法二,其实很多人更愿意用第一种方法,因为不需要多声明一个len变量,但是其实相对于大一点的数组,可以使用方法二,先将数组的长度缓存到一个变量len种,循环就不需要每次都去执行arr.length这一个方法了。对于第三种方法其实是将取值与判断进行合并,然后不停枚举直到为空。

比较

对于三种循环方式,我们使用将每一个数字push到一个新的数组中(可以理解为进行一个简单的操作,适当增大时间,从而可以看出对比差距),通过console.timeconsole.timeEnd的差值来判断执行效率。

先上比较代码

代码语言:javascript
复制
var arr = [] // 这里创建数组的步骤就省略
for(let j = 1; j <= 9999999; j++) {
	arr.push(j);
}
function method1() {
	var arr1 = [];
	console.time('方法1')
	for(let i = 0; i < arr.length; i++) { 
		arr1.push(arr[i]);
	}
	console.timeEnd('方法1')
}

function method2() {
	var arr2 = [];
	console.time('方法2')
	for(let i = 0, len = arr.length; i < len; i++) { 
		arr2.push(arr[i]);
	}
	console.timeEnd('方法2')
}

function method3() {
	var arr3 =[];
	console.time('方法3')
	for(let i = 0, arrValue; arrValue = arr[i]; i++) { 
		arr3.push(arrValue)
	}
	console.timeEnd('方法3')
}
method1();
method2();
method3();

Alt text

测试多次其实可以得到一个结论,数据很多时,最常见for循环的写法,不再是最优,可以看出它与方法二三都有一定的差距。

es6新方法

for in这种用于遍历对象的就不示例了,实用性不大,所以就列出以下几种方法的使用,与效率代码(forEach、 map、 for of

还是照样付代码和结论:

代码语言:javascript
复制
function method4() {
  var arr4 = []
  console.time('方法4')
  arr.forEach((item) => {
    arr4.push(item)
  })
  console.timeEnd('方法4')
}

function method5() {
  var arr5 = []
  console.time('方法5')
  arr5 = arr.map(item => item)
  console.timeEnd('方法5')
}

function method6() {
  var arr6 = []
  console.time('方法6')
  for (let item of arr) {
    arr6.push(item)
  }
  console.timeEnd('方法6')
}

method1();
method2();
method3();
method4();
method5();
method6();

时间比较(单位ms同时省略小数点后面的数字)

方法一

方法二

方法三

方法四

方法五

方法六

314

279

290

412

198

424

323

288

283

428

207

1171

352

294

288

414

196

442

286

284

295

445

194

378

由上表可以看出,forEachfor of方法比传统的for循环效率效率更低,但map确实出乎意料的高效率,我想了想,可能是因为map有一个返回值,所以说它无需重新调用push方法,所以有一定优势。

但是虽然说forEachfor of效率相对较低,甚至图表中出现了不稳定的现象,但是终究这些es6的方法有方便之处,比如for of直接对每个数值进行遍历,而省去了使用arr[index]这种步骤。

但是根据网上的说法,不同浏览器它们对于不同方法响应不同,于是默默打开safari,比较了一下...(乱码咱就不care了)

Alt text

Alt text

果不其然,ios对开发的支持效果是真的好。(难怪开发都喜欢用mac哈哈哈)

总结

还是回归到原来,但从简单业务上来讲,for循环可谓是简单高效,但是网上经常言传es6高效循环等等,实际是我觉得可能是在说针对某一业务场景,使用es6的便利性更高,代码更简洁吧(这里并不是指狭义的运行时间,还要考虑开发成本,比如重复赘余的写arr[i]这种)。并且最后一点告诉我们,浏览器也很重要,这对各大浏览器制造商也是一个极大的考验,毕竟这个时间差对于用户体验来讲,还是值得去最小化的~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • js循环方法
  • for循环
    • 比较
    • es6新方法
    • 总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档