下面是测试例子可以直接在nodejs上跑
一些预料之外结果是
- 访问 get set 性能开销是访问普通属性 5倍左右, 比普通的函数调用还慢
- map get元素性能开销有时快有时慢不稳定,与元素数量有关
- 使用 object[key] 的方式访问 属性性能开销是object.var的2倍左右, 估计与元素数量有关
- index+=1 比 index++速度快
- 矩形包围盒判断性能开销主要是在属性访问上, if 判断性能开销几乎忽略不计
- map key用 string与number类型性能最好
- for of 的写法比普通的循环慢2倍左右
性能瓶颈貌似在内存访问速度上
测试结果在备注里
function testMapPerformance(numElements) {
// 创建一个新的Map
const myMap = new Map();
const emyptyMap = new Map();
let int_key = 23;
let float_key = 23.1;
let str_key = 'my_key';
let symbol_key = Symbol();
let arr = []
const mcv = {
mcdksc: false,
mcv: { a:{b:{c:{d:{e:{}}}}},x:23.13,},
get get_this_mcv() { return this.mcv; },
x: 2031.34, y: 2491.201/3.3, w: 200.3, h: 423.1
};
// 向Map中添加元素
for (var i = 0; i < numElements; i++) {
myMap.set(Symbol(), Symbol());
arr.push(Symbol());
// mcv[i] = 1;
}
myMap.set(int_key, 1);
myMap.set(float_key, 1);
myMap.set(str_key, 1);
myMap.set(symbol_key, 1);
let outside = 1
const obj = {id : "mcv"}
const keytest = 'mcv';
function tst() { return mcv.mcv; }
function EmptyFunc(i) {outside = i}
function forFunc(){
for (let i = 0; i < 1; i++) {
outside = i
}
}
// 递归调用函数
let index = 0,len = arr.length
function callFunc(){
index++;
if(index < len){
callFunc();
}
}
let testNum = 2;
let pool = new Array(len);
let offset = 1;
function poolPut(v){
pool[offset] = v;
offset++;
}
function poolPool(){
if(offset == 0){
return;
}
offset--;
return pool[offset];
}
poolPut({a:1, b:2})
// 记录开始时间
let startTime = performance.now();
// callFunc() // 8.145099999999997毫秒
// forFunc()
for (; index < len; index+=1) {
// 运行测试代码 空循环耗时: 0.7192999999999969毫秒
// let m = mcv[index]; // 1.0782999992370605毫秒
// let m = arr[index] // 1.091599941253662毫秒
// let m = pool[index] // 1.091599941253662毫秒
// let m = mcv; // 1.0738999843597412毫秒
// let m = mcv.mcv; // 1.3427000045776367毫秒
// let m = mcv['mcv']; // 1.3657000064849854毫秒
// let m = mcv[keytest]; // 1.5729000568389893毫秒
// let m = mcv[obj.id]; // 1.7720000743865967毫秒
// let m = mcv.mcv.a.b.c.d.e; // 1.7039000988006592毫秒
// let m = tst(); // 1.8094000816345215毫秒
// let m = tst().a.b.c.d.e; // 1.9147999286651611毫秒
// let m = mcv.get_this_mcv; // 2.73009991645813毫秒
// let m2 = myMap.get(index); // 4.779200000000003毫秒
// let m2 = myMap.get(str_key); // 1.370199999999997毫秒
// let m2 = myMap.get(int_key); // 1.3554999999999993毫秒
// let m2 = myMap.get(float_key); // 1.7979999999999947毫秒
// let m2 = myMap.get(symbol_key); // 1.7554999999999978毫秒
// let m2 = emyptyMap.get(index); // 1.3554999999999993毫秒
// mcv[index] = 1; // 3.0701000000000036毫秒
// delete mcv[index]; // 31.150600000000004毫秒
// let isRect = mcv.x > 200 && mcv.y > 2000 && mcv.x + mcv.w < 200 && mcv.y +mcv.h <2001; // 2.4273000000000025毫秒
// let isRect = testNum > index || testNum < index || testNum > len || index >= len; // 1.1011999999999986毫秒
// mcv.x = index; // 1.2391000000000005毫秒
// 总耗时 6.143899999999995毫秒
// let col = ( mcv.x / mcv.w) | 0; // 3.6865999999999985毫秒
// let row = (( mcv.y - mcv.h) / mcv.h) | 0; // 4.951900000000002毫秒
// let gid = mcv.x * index + index; // 2.695599999999999毫秒
// let airId = arr[index]; // 1.5437999999999903毫秒
// let airId2 = arr[index]; // 1.5437999999999903毫秒
// testNum+1 * 2 + 2 -3; // 0.9227999999999952毫秒
// const m = Math.pow(10 , 4) // 1.1916999999999973毫秒
// forFunc(); // 1.2959999999999994毫秒
// EmptyFunc(); // 0.9909999999999997毫秒
// const m = Math.round(i*1000) / 1000
// const m = pool.pop(); // 1.3101999999999947毫秒
// pool.push(mcv); // 2.5149999999999935毫秒
// const m = poolPool(); // 1.2903999999999982毫秒
// poolPut(mcv); // 2.118399999999994毫秒
// const m = {} // 1.6015999999999977毫秒
// const m = {b:2,a:1} // 1.6015999999999977毫秒
// const m = {}; m.b=2; m.a=1; // 1.6毫秒
// const m = []; // 1.4691000000000045毫秒
// let m = 1; m ++; // 0.9345999999999961毫秒
// outside++; // 1.0360999999999976毫秒
// outside+=1; // 0.9040000000000035毫秒
// outside+=index; // 1.2355000000000018毫秒
}
// myMap.forEach((value, key)=>{
// })
// 记录结束时间
const endTime = performance.now();
// 计算并打印耗时
console.log(`操作耗时:${endTime - startTime}毫秒`, outside);
}
// 10w次循环耗时测试
testMapPerformance(100000)