关于JS try catch的性能问题

最近项目里,为了方便错误消息捕捉进logs里面
我用了一大堆try catch
然后,突然想起来try catch可能会消耗性能
网上找了个帖子,说是以前阿里用来测试的

设计实验方式

简单的设计方案也就是对比实验。

空白组1:[无 try catch 的情况下对数据取模1千万次耗时]

 

 !function() {
 //无try catch的情况耗时
 var t = new Date();
 //耗时代码开始
 for (var i = 0; i < 100000000; i++) {
 var p = i % 2;
 }
 //耗时代码结束
 document.write(new Date() - t);
 }();

参照组2:[将耗时代码用 try 包围,内联耗时代码]

 

!function() {
 //在 try 中内联代码的耗时情况
 var t = new Date();
 try{
 //耗时代码开始
 for (var i = 0; i < 100000000; i++) {
 var p = i % 2;
 }
 //耗时代码结束
 throw new Error();
 }catch(e){
 }
 document.write(new Date() - t);
 }();

参照组3:[将耗时代码用 try 包围,外联耗时代码]

 

!function() {
 function run(){
 //耗时代码开始
 for (var i = 0; i < 100000000; i++) {
 var p = i % 2;
 }
 //耗时代码结束
 }
 //在 try 中内联代码的耗时情况
 var t = new Date();
 try{
 run();
 throw new Error();
 }catch(e){
 }
 document.write(new Date() - t);
 }();

参照组4:[将耗时代码用 catch 包围,内联耗时代码]

 

!function() {
 //在 catch 中内联代码的耗时情况
 var t = new Date();
 try{
 throw new Error();
 }catch(e){
 //耗时代码开始
 for (var i = 0; i < 100000000; i++) {
 var p = i % 2;
 }
 //耗时代码结束
 }
 document.write(new Date() - t);
 }();

参照组5:[将耗时代码用 catch 包围,外联耗时代码]

 

!function() {
 function run(){
 //耗时代码开始
 for (var i = 0; i < 100000000; i++) {
 var p = i % 2;
 }
 //耗时代码结束
 }
 //在 catch 中内联代码的耗时情况
 var t = new Date();
 try{
 throw new Error();
 }catch(e){
 run();
 }
 document.write(new Date() - t);
 }();

运行结果(只选取了 Chrome 作为示例)

Chrome44

不使用 try-catch try 中耗时,内联代码 try 中耗时,外联代码 catch 中耗时,内联代码 catch 中耗时,外联代码
98.2 1026.9 107.7 1028.5 105.9

我当时就慌得一笔,写了那么多代码还要改回来,差点就哭了

**然后我就在现在用的chrome 81里面跑了同样的代码
而结果是**

**Chrome81

不使用 try-catch try 中耗时,内联代码 try 中耗时,外联代码 catch 中耗时,内联代码 catch 中耗时,外联代码
69 67 66 61 61**

**然后我又把循环次数加了10倍
耗时基本上是线性的增加了10倍**

**??????
chrome已经牛逼的彻底解决了try catch的性能问题了吗?
诸位认为呢?**

阅读 6.7k
2 个回答

是的,V8 引擎做了优化,从版本 5.3 开始加入了相应的编译开关,但只作为了可选项。从版本 6.0 开始就默认选项了,此时对应 Chrome 版本是 2017 年 7 月发布的 60.0,对应 Node.js 是版本 8.3。

V8 有关此优化开关的提交记录:https://github.com/v8/v8/comm...


如果是游戏之类的,可能还要担心一些性能问题,毕竟操作反馈要及时。如果你就是个普通的网站,有点儿 CRUD 之类的操作,大可不必担心性能开销。开销只在抛出异常时才会产生,你这得是写成了啥样的代码了能循环连抛几万个异常?

不太确定,这要深入阅读 V8 源码,暂时没工夫去看。

不过,乱加 try...catch... 和不加 try...catch... 一样,都是不良实践。应该是 可能出错 的地方才 try...catch...,大部分逻辑代码不需要加。

最常见需要 try...catch... 的地方是网络请求,因为网络请求可能存在连接异常、连接超时、切换中断等问题,这些都应该捕获并且告知用户。如果是请求的数据有问题,比如权限不对、重复操作等,就不需要捕获,直接由后端拒绝后显示返回的错误信息即可。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题