try catch的性能问题
最近在给项目做性能优化, 就推测JS的try catch是否会存在性能问题. 百度搜索了一下, 确实有很多相关的文章. 我索性自己做一个实验来验证一下这个猜测.
1. 不发生异常时
代码如下, 启动10万次运行, try catch 一个简单的函数执行.
function doSomething() {
let b = { c:1 };
return b.c;
}
function testTryCatch(func) {
let ret = 0;
try {
ret = func();
} catch (error) {
ret = -1;
}
return ret;
}
function repeatTimesDelay(func, times) {
let start = Date.now();
let ret = 0;
for (var i = 0; i < times; ++i) {
ret = testTryCatch(func);
}
console.log(`ret: ${ret}`);
return Date.now() - start;
}
let delay = repeatTimesDelay(doSomething, 100000);
console.log(`delay: ${delay}`);
运行结果:
ret: 1
delay: 8
2. 发生异常时
后面的.e访问将触发异常.
function doSomething() {
let b = { c:1 };
return b.c.d.e;
}
执行结果: 时长从毫秒级变成了秒级, 性能大大的被拉低.
ret: -1
test.js:27
delay: 2178
3. 优化
对需要访问的key做保护处理
function doSomething() {
let b = { c:1 };
let c = b.c || {};
let d = c.d || {};
return d.e;
}
执行结果: 时长又回到了毫秒级.
ret: undefined
test.js:28
delay: 8
总结
这里的例子比较特殊的地方在于, 一般情况下try catch不在十万次的循环中连续发生异常, 不过如果刚好在循环体中, 这个优化还是值得的, 也就是说在循环体中, 不要太依赖try catch来帮助处理本可以代码避免的异常.