Javascript集与阵列性能

Javascript集与阵列性能,javascript,arrays,performance,set,iteration,Javascript,Arrays,Performance,Set,Iteration,这可能是因为集合对Javascript来说相对较新,但我在StackO或其他任何地方都找不到一篇文章讨论Javascript中两者的性能差异。那么,就性能而言,两者有什么不同?具体来说,当涉及到删除、添加和迭代时。好的,我已经测试了从数组和集合中添加、迭代和删除元素。我运行了一个“小”测试,使用10000个元素,以及一个“大”测试,使用100000个元素。以下是结果 console.time("set") var s = new Set() for(var i = 0; i < 10000

这可能是因为集合对Javascript来说相对较新,但我在StackO或其他任何地方都找不到一篇文章讨论Javascript中两者的性能差异。那么,就性能而言,两者有什么不同?具体来说,当涉及到删除、添加和迭代时。

好的,我已经测试了从数组和集合中添加、迭代和删除元素。我运行了一个“小”测试,使用10000个元素,以及一个“大”测试,使用100000个元素。以下是结果

console.time("set")
var s = new Set()
for(var i = 0; i < 10000; i++)
  s.add(Math.random())
s.forEach(function(e){
  s.delete(e)
})
console.timeEnd("set")
console.time("array")
var s = new Array()
for(var i = 0; i < 10000; i++)
  s.push(Math.random())
s.forEach(function(e,i){
  s.splice(i)
})
console.timeEnd("array")
向集合中添加元素 无论添加的元素数量如何,
.push
数组方法似乎比
.add
set方法快4倍左右

迭代和修改集合中的元素 对于测试的这一部分,我使用了一个
For
循环来迭代数组,使用
For of
循环来迭代集合。同样,迭代数组的速度更快。这一次似乎是指数级的,因为在“小”测试中花费的时间是原来的两倍,而在“大”测试中花费的时间几乎是原来的四倍

从集合中删除元素 这就是它变得有趣的地方。我使用
for
循环和
拼接
的组合从数组中删除一些元素,并使用
for of
删除
从集合中删除一些元素。对于“小”测试,从集合中移除项目的速度大约快了三倍(2.6 ms vs 7.1 ms),但对于“大”测试,从阵列中移除项目需要1955.1 ms,而从集合中移除项目只需要83.6 ms,速度快了23倍

结论 在10k元素时,两个测试运行的时间相当(阵列:16.6毫秒,集合:20.7毫秒),但在处理100k元素时,集合是明显的赢家(阵列:1974.8毫秒,集合:83.6毫秒),但这仅仅是因为移除操作。否则阵列会更快。我说不出确切的原因

我尝试了一些混合场景,其中创建并填充了一个数组,然后将其转换为一个集合,在该集合中删除一些元素,然后将该集合重新转换为一个数组。尽管这样做会比删除数组中的元素提供更好的性能,但从集合中传输到集合所需的额外处理时间超过了填充数组而不是集合所带来的好处。最后,只处理一个集合会更快。不过,这是一个有趣的想法,如果选择使用数组作为一些没有重复数据的大数据的数据收集,从性能角度来看,这可能是有利的,如果需要在一次操作中删除多个元素,要将数组转换为集合,请执行删除操作,并将集合转换回数组

数组代码:

var timer=函数(名称){
var start=新日期();
返回{
停止:函数(){
var end=新日期();
var time=end.getTime()-start.getTime();
log('Timer:',name,'finished in',time,'ms');
}
}
};
var getRandom=函数(最小值、最大值){
返回Math.random()*(max-min)+min;
};
var lastNames=[“史密斯”、“约翰逊”、“威廉姆斯”、“琼斯”、“布朗”、“戴维斯”、“米勒”、“威尔逊”、“摩尔”、“泰勒”、“安德森”、“托马斯”];
var genLastName=函数(){
var index=Math.round(getRandom(0,lastNames.length-1));
返回lastNames[索引];
};
变量性别=[“男性”、“女性”];
var genSex=函数(){
var指数=数学圆(getRandom(0,sex.length-1));
回归性[指数];
};
var Person=函数(){
this.name=genLastName();
this.age=Math.round(getRandom(01100))
this.sex=“男性”
};
var genPersons=函数(){
对于(变量i=0;i<100000;i++)
推送(新人物());
};
var changeSex=函数(){
for(var i=0;i
观察结果

  • 集合操作可以理解为执行流中的快照
  • 我们面前不是一个确定的替代品
  • 集合类的元素没有可访问的索引
  • Set类是数组类的补充,在需要存储要应用基本加法的集合的场景中非常有用, 删除、检查和迭代操作
我分享一些性能测试。尝试打开控制台并复制粘贴下面的代码

创建阵列(125000)

1。查找索引

我们比较了集合的has方法和数组indexOf:

数组/indexOf(0.281ms)|集合/具有(0.053ms)

//助手
var checkArr=(arr,item)=>arr.indexOf(item)!=-1.
var checkSet=(集合,项)=>set.has(项);
//瓦尔斯
var集,结果;
控制台时间('timeTest');
结果=检查arr(arr,123123);
控制台.timeEnd('timeTest');
集合=新集合(arr);
控制台时间('timeTest');
支票套(套,123123);
控制台.timeEnd('timeTest');
2。添加新元素

我们分别比较Set和Array对象的add和push方法:

数组/推送(1.612ms)|设置/添加(0.006ms)

console.time('timeTest');
arr.push(n+1);
控制台.timeEnd('timeTest');
集合=新集合(arr);
控制台时间('timeTest');
集合。添加(n+1);
控制台.timeEnd('timeTest');
控制台信息(arr.length);//125001
console.info(set.size);//125001
3。删除
set: 7.787ms
array: 2.388ms
var n = 125000;
var arr = Array.apply( null, Array( n ) ).map( ( x, i ) => i );
console.info( arr.length ); // 125000