有一个需求:从类似下面数组中,将 id 提取出来,放入另一个数组中:
const a = [
{
test:[{id:1},{id:2}]
},{
test:[{id:3},{id:4},{id:5}]
},{
test:[{id:6},{id:7},{id:8}]
},{
test:[{id:9}]
}
]
对于这个问题,首先我想到的是这个方案:
function convert(a){
const b = [];
a.forEach(v1 => {
const tmp = [];
v1.test.forEach(v2 => tmp.push(v2))
b.push(...tmp)
})
return b;
}
如果将 forEach
换成普通的 while
循环,应该会具备更快的运行速度:
function conver2(a){
const b = [];
let i = 0;
let arrLen = a.length;
while(i < arrLen){
let testLen = a[i].test.length;
let j = 0;
while(j < testLen){
b.push(a[i].test[j])
j++
}
i++
}
return b;
}
冥冥之中,我感觉是可以通过一层循环来解决这个问题的,于是想出了第三种方案:
function convert3(a){
let i = j = 0;
let testLen = a[j].test.length;
let arrLen = a.length;
let b = [];
while(j < arrLen){
b.push(a[j].test[i].id);
i++
if(i == testLen){
j++;
i = 0
if(j < arrLen){
testLen = a[j].test.length
}
}
}
return b;
}
为了衡量三种算法的性能,需要使用较大的操作数量,于是我将代码做了一些修改,来统计这三个方法各自的执行时间:
const a = [
{
test:[{id:1},{id:2}]
},{
test:[{id:3},{id:4},{id:5}]
},{
test:[{id:6},{id:7},{id:8}]
},{
test:[{id:9}]
}
]
for(let i = 0; i < 1000000;i ++){
a.push(a[i % a.length])
}
function convert1(a,index){
console.time("start-convert1-"+index);
const b = [];
a.forEach(v1 => {
const tmp = [];
v1.test.forEach(v2 => tmp.push(v2))
b.push(...tmp)
})
console.timeEnd("start-convert1-"+index);
}
function convert2(a,index){
console.time("start-convert2-"+index);
const b = [];
let i = 0;
let arrLen = a.length;
while(i < arrLen){
let testLen = a[i].test.length;
let j = 0;
while(j < testLen){
b.push(a[i].test[j])
j++
}
i++
}
console.timeEnd("start-convert2-"+index);
}
function convert3(a,index){
console.time("start-convert3-"+index);
let i = j = 0;
let testLen = a[j].test.length;
let arrLen = a.length;
let b = [];
while(j < arrLen){
b.push(a[j].test[i].id);
i++
if(i == testLen){
j++;
i = 0
if(j < arrLen){
testLen = a[j].test.length
}
}
}
console.timeEnd("start-convert3-"+index);
}
for(let i = 0; i < 10; i++){
convert1(a,i)
convert2(a,i)
convert3(a,i)
}
运行结果如下:
start-convert1-0: 151.4248046875ms
start-convert2-0: 75.463134765625ms
start-convert3-0: 59.9140625ms
start-convert1-1: 133.663818359375ms
start-convert2-1: 54.760986328125ms
start-convert3-1: 58.22607421875ms
start-convert1-2: 135.48095703125ms
start-convert2-2: 56.72314453125ms
start-convert3-2: 53.788818359375ms
start-convert1-3: 147.720703125ms
start-convert2-3: 58.44091796875ms
start-convert3-3: 54.409912109375ms
start-convert1-4: 143.4169921875ms
start-convert2-4: 55.30810546875ms
start-convert3-4: 51.42578125ms
start-convert1-5: 144.20703125ms
start-convert2-5: 57.093017578125ms
start-convert3-5: 51.152099609375ms
start-convert1-6: 143.78076171875ms
start-convert2-6: 54.94775390625ms
start-convert3-6: 51.739013671875ms
start-convert1-7: 147.794921875ms
start-convert2-7: 57.3330078125ms
start-convert3-7: 54.512939453125ms
start-convert1-8: 148.298095703125ms
start-convert2-8: 55.76806640625ms
start-convert3-8: 54.154052734375ms
start-convert1-9: 153.4873046875ms
start-convert2-9: 54.783203125ms
start-convert3-9: 55.839111328125ms
在十次的测试中,第三种方法的成绩最好,其次是第二种方式,但二者差距不大。使用 forEach
的第一种方法性能最差。抽象级别越高的方法,性能越弱。
完。
网友评论