昨天面试被问到JS里数组去重的方法,于是把最常用的for + object方法说了(当时本来准备说es6的Set去重的,结果突然忘记Set了)。
完事在网上搜了下去重的方法,发现远不止当时想到的两种,找了几种常用的方法,做了下执行效率对比,发现在处理大数据量的时候,竟然出现了将近一千倍的差距。为之震惊…
一、常用8种方法执行效率对比(总15w条数据)
1.method.js
1 | let obj = { |
2.main.js(len1+len2为数组总长度)
1 | let len1 = 100000; |
3.执行结果分析
1 | filter + indexOf |
惊讶的发现,执行时间最短的依次是:for…of + object < for + object = filter + object < Set < Array.sort < for + indexOf < for…of + includes < filter + indexOf。
并且最长的执行时间 10608ms 竟然比最短的 12ms 多了将近1000倍(仅仅15w条数据的情况下)。
粗略的总结下规律:
1.循环中用对象属性来判断要比数组查找快的多(filter+indexOf和filter+object对比可以看出;以及for+object和for+indexOf对比可以看出)
2.数组查找indexOf和includes执行效率差不多(for+indexOf和for…of+includes可以看出)
3.数组循环for…of和for差不多(for+object和for…of+object可以看出)
4.Array.sort和Set比基本2倍快
为了更明显的看出差别,我们把测试数据量扩大一个数量级(150w)再测一次,测试结果如下:
1 | filter + object |
你可能发现了,测试结果里没有filter+indexOf、for+indexOf、for…of+includes,是因为150w条数据的时候,这几个方法直接卡死不动了(跟15w条的结果比,不止是10倍的关系),尴尬…
再次对比结果发现:
1.再次印证了上面中的规律1(indexOf要比对象属性慢得多)
2.for+object要比for…of+object稍快,filter+object次之
3.Set比Array.sort快,但到不了第一种情况下的2倍差距
二、结果分析
从两次测试不难发现,在实际项目中,尽量用for+object(或者for…of+object和filter+object);如果为了代码简洁,可以用es6的Set,在实际运用中,数据量不大的情况,差别还是可以接受的;千万不能用indexOf或者includes,简直就不是一个数量级。
** 突然想到刚毕业时做.net,一次老大开会指出『千万不能把数据库数据都读到内存中操作,而应先从数据库中筛选出符合条件的数据,然后放到内存中操作,否则大数据量的时候可能会把服务器搞崩』。当时还不以为然,也没做实际对比。今天通过上面的实际测量,才发现差距之大,不由得汗颜,之前写代码的随性…仅以此文告诫自己吧!!!