前面讲了json数组的高性能去重方法:
今天说说js数组的合并的四种方法,后面会有实例性能对比,先列出这四种方法:
- concat()方法:array1.concat(array2)
- 扩展运算符:[…array1, …array2]
- push()+扩展运算符:array1.push(…array2)
- 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]扩展运算符只能说只是写起来更加容易理解罢了,不考虑性能时可以用;