js性能对比之合并数组的四种方法

时间: 作者:admin 浏览:

前面讲了json数组的高性能去重方法:

js中json对象数组array去重的高性能方法

今天说说js数组的合并的四种方法,后面会有实例性能对比,先列出这四种方法:

  1. concat()方法:array1.concat(array2)
  2. 扩展运算符:[…array1, …array2]
  3. push()+扩展运算符:array1.push(…array2)
  4. Array.prototype.push.apply(array1, array2)

使用方法一看就懂,没太多好讲的,经过小编的测试,先大概聊一聊这几个方法:

concat()可以说是最稳健的一个方法,无论数据量大小,concat()方法都能应付,且性能可观,兼容性强;

至于使用扩展运算符来合并数组,应该已经成为开发者当下最流行的写法了,只因为写起来简便,这也是ES官方所期待的,扩展运算符可以说又立一功,但性能就不一定高了;

至于push(…array)方法,并不常见用在合并数组中,一般只是用来给数组增加一个新元素array.push(“xxx”),一般人不知道它还有第二、三个参数,可以同时新增多个元素array.push(a1, a2, a3…),但是它参数的个数又不是无限的,后面的测试会发现,push的参数超过13万时就会报错,所以超10万数据量时不太推荐用push来合并数组,但是小数据量数组合并的性能比concat()高,竟想不到被push()秒杀了,出乎意料;

另外,Array.prototype.push.apply(array1, array2)与push(…array)相差不大,是普通数据量数组合并最快的方法了;

下面我们来测试各个方法在不同数据量级下的时间(后面给出数据对比表格):

concat()方法:

测试1:两个1万、10万、100万元素的数组合并时间:0.05ms、1.1ms、5.1ms

let testArray1 = [],testArray2 = [];for(let i=0;i<10000;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
let result = testArray1.concat(testArray2)
console.timeEnd()
console.log(result)

结果图:


测试2:两个只有10个元素的数组合并1万次、10万次的时间:1212ms、187600ms(3.1分钟)

let testArray1 = [],testArray2 = [];for(let i=0;i<10;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
for(let j=0;j<10000;j++){
    testArray1 = testArray1.concat(testArray2)
}
console.timeEnd()
console.log(result)

结果图:

测试3:两个10万元素的数组合并10次、100次的时间:45ms、2617ms

let testArray1 = [],testArray2 = [];for(let i=0;i<100000;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
for(let j=0;j<10;j++){
    testArray1 = testArray1.concat(testArray2)
}
console.timeEnd()
console.log(testArray1)

结果图:

扩展运算符:[…array1, …array2]

测试1:两个1万、10万、100万元素的数组合并时间:1.83ms、16.2ms、86.5ms

let testArray1 = [],testArray2 = [];for(let i=0;i<10000;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
let result = [...testArray1, ...testArray2]
console.timeEnd()
console.log(result)


测试2:两个只有10个元素的数组合并1万次、10万次的时间:22449ms、3185859ms(53分钟:你没看错,为了等这个结果,小编打了一把王者再回来看的)

let testArray1 = [],testArray2 = [];for(let i=0;i<10;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
for(let j=0;j<10000;j++){
    testArray1 = [...testArray1, ...testArray2]
}
console.timeEnd()
console.log(testArray1)

结果图:

测试3:两个10万元素的数组合并10次、100次的时间:389ms、29147ms

let testArray1 = [],testArray2 = [];for(let i=0;i<100000;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
for(let j=0;j<10;j++){
    testArray1 = [...testArray1,...testArray2]
}
console.timeEnd()
console.log(testArray1)

结果图:

push()+扩展运算符:array1.push(…array2)

测试1:两个1万、10万、100万元素的数组合并时间:0.1ms、2.87ms、(报错:Uncaught RangeError: Maximum call stack size exceeded at ‹anonymous›:3:12)

let testArray1 = [],testArray2 = [];for(let i=0;i<10000;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
testArray1.push(...testArray2)
console.timeEnd()
console.log(testArray1)

结果图:

如上图所示,这就是小编刚开始说的,push()方法的参数超过一定数量就会报错,针对这个参数,下面我们再来测试10万以上的数据,发现超过13万就报错了,如下图:

测试2:两个只有10个元素的数组合并1万次、10万次、100万次的时间:3.2ms、20ms、266ms

let testArray1 = [],testArray2 = [];for(let i=0;i<10;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
for(let j=0;j<10000;j++){
    testArray1.push(...testArray2)
}
console.timeEnd()
console.log(testArray1)

结果图:


测试3:两个10万元素的数组合并10次、100次的时间:30ms、319ms

let testArray1 = [],testArray2 = [];for(let i=0;i<100000;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
for(let j=0;j<10;j++){
    testArray1.push(...testArray2)
}
console.timeEnd()
console.log(testArray1)

结果图:

Array.prototype.push.apply(array1, array2)

测试1:两个1万、10万、100万元素的数组合并时间:0.08ms、2.09ms、(报错:Uncaught RangeError: Maximum call stack size exceeded at ‹anonymous›:3:22)

let testArray1 = [],testArray2 = [];for(let i=0;i<10000;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
Array.prototype.push.apply(testArray1, testArray2)
console.timeEnd()
console.log(testArray1)

结果图:

测试2:两个只有10个元素的数组合并1万次、10万次、100万次的时间:3.7ms、24ms、266ms

let testArray1 = [],testArray2 = [];for(let i=0;i<10;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
for(let j=0;j<10000;j++){
    Array.prototype.push.apply(testArray1, testArray2)
}
console.timeEnd()
console.log(testArray1)

结果图:


测试3:两个10万元素的数组合并10次、100次的时间:23ms、314ms

let testArray1 = [],testArray2 = [];for(let i=0;i<100000;i++){testArray1.push({id:i,name:"item"+i});testArray2.push({value:i+1,label:"label"+i+1})}
console.time()
for(let j=0;j<10;j++){
    Array.prototype.push.apply(testArray1, testArray2)
}
console.timeEnd()
console.log(testArray1)

结果图:

总结:

测试1:两个1万、10万、100万元素的数组合并时间对比表:

方法 \ 数据量 1万 10万 100万
array1.concat(array2) 0.05ms 1.1ms 5.1ms
[…array1, …array2] 1.83ms 16.2ms 86.5ms
array1.push(…array2) 0.1ms 2.87ms 报错
Array.prototype.push.apply(array1, array2) 0.08ms 2.09ms 报错

测试2:两个只有10个元素的数组合并1万次、10万次、100万次的时间对比表:

方法 \ 合并次数 1万 10万 100万
array1.concat(array2) 1212ms 187600ms(3.1分钟) x
[…array1, …array2] 22449ms 3185859ms(53分钟) x
array1.push(…array2) 3.2ms 20ms 266ms
Array.prototype.push.apply(array1, array2) 3.7ms 24ms 266ms

测试3:两个10万元素的数组合并10次、100次的时间对比表:

方法 \ 合并次数 10 100 1000
array1.concat(array2) 45ms 2617ms x
[…array1, …array2] 389ms 29147ms x
array1.push(…array2) 30ms 319ms x
Array.prototype.push.apply(array1, array2) 23ms 314ms x

从以上对比表总结可得知:

1、数组元素量级大而合并次数少时,性能对比:
concat() > push() > […array1,…array2]
2、数组元素少但合并次数多时,性能对比:
push() > concat() > […array1,…array2]

3、push()方法适合10万级以下元素的数组合并,次数越多越有优势,但push()怕数组元素多,超过12万左右就会报错,导致无法合并数组,同时两种push()用法性能相差不大;
4、concat()方法适合数组元素量级大,但是合并次数少的情况,当数组合并频繁的时候性能表现略差;
5、[…array1, …array2]方法无论是大量级数组合并还是数组频繁合并,都不占优势,单从性能方面来说,是最差的一种,而且差距比较大…….有点意外;

综合对比来说: push() > concat() > […array1,…array2]

这次的数组合并测试结果,相信大家差不多心中有数了:

可以说一般情况下,用push()方法合并数组是最快的方法,concat()方法可以支撑大量级数组合并,而[…array1,…array2]扩展运算符只能说只是写起来更加容易理解罢了,不考虑性能时可以用;

微信公众号
微信公众号:
  • 前端全栈之路(微信群)
前端QQ交流群
前端QQ交流群:
  • 794324979
  • 734802480(已满)

更多文章

栏目文章


Copyright © 2014-2023 seozhijia.net 版权所有-粤ICP备13087626号-4