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來幫助處理本可以代碼避免的異常.