当没有任何异常被抛出时,使用多个try-catch块是否“慢”?我的问题与this one相同,但对于Javascript。
假设我有20个函数,其中包含try-catch块。另一个函数调用这20个函数中的每一个。他们都不会抛出异常。由于这个try-catch块,我的代码执行速度会更慢或执行得更糟吗?
答案 0 :(得分:46)
你在做典型的CRUD UI代码吗?使用try catches,使用循环到10000,无缘无故地撒在你的代码中,地狱,使用angular / ember - 你不会注意到任何性能问题。
如果您正在进行低级库,物理模拟,游戏,服务器端等,那么永不投掷的try-catch块通常根本不重要,但问题是V8在其优化编译器中不支持它直到引擎的第6版,所以语法上包含try catch的整个包含函数将不会被优化。您可以通过创建类似tryCatch
的辅助函数:
function tryCatch(fun) {
try {
return fun();
}
catch(e) {
tryCatch.errorObj.e = e;
return tryCatch.errorObj;
}
}
tryCatch.errorObj = {e: null};
var result = tryCatch(someFunctionThatCouldThrow);
if(result === tryCatch.errorObj) {
//The function threw
var e = result.e;
}
else {
//result is the returned value
}
在V8第6版(随Node 8.3和最新Chrome一起提供)之后,try-catch
内的代码性能与普通代码相同。
答案 1 :(得分:36)
最初的问题是在没有抛出错误时询问try / catch的成本。使用try / catch保护代码块时肯定会产生影响,但是当受保护的代码变得更加复杂时,try / catch的影响将很快消失。
考虑这个测试:http://jsperf.com/try-catch-performance-jls/2
一个简单的增量每秒运行356,800,000次迭代 try / catch中的相同增量是每秒93,500,000次迭代。由于try / catch,这是75%的开销。 但是,一个简单的函数调用每秒运行112,200,000次迭代。 2个简单的函数调用以每秒61,300,000次迭代运行。
此测试中未执行的尝试比一个简单的函数调用花费的时间略多。这几乎不是速度惩罚,除了像FFT这样真正强烈的内部循环之外。
您要避免的情况是实际抛出异常的情况。这非常慢,如上面的链接所示。
编辑:这些数字适用于我的计算机上的Chrome。在Firefox中,未执行的尝试与根本没有保护之间没有显着差异。如果没有抛出异常,使用try / catch基本上没有任何惩罚。
答案 2 :(得分:7)
据说try-catch
区块很贵。但是,如果关键性能不是问题,使用它不一定是一个问题。
罚款IMO:
可读性:使用大量的try-catch管理您的代码是丑陋和分散注意力的
不合适:如果你的代码不受异常崩溃的影响,那么插入这样的块是一个坏主意。只有在您的代码中出现故障时才插入它。请查看以下主题:When to use try/catch blocks?
异步:try-catch
块是同步的,在async
编程时无效。在ajax
请求期间,您可以在专用回调中处理error
和success
个事件。无需try-catch
。
希望这有帮助,
R上。
答案 3 :(得分:6)
我尝试根据具体的基准测试结果提供答案。为此,我编写了一个简单的基准测试,它将 try-catch 与各种 if-else 条件进行比较,从简单到更复杂。我知道基准可能会因平台而异。如果您得到不同的结果,请发表评论。请参阅try-catch benchmark here。
首先,我尝试以紧凑的方式表示这里的测试套件。有关完整详细信息,请参阅上面的链接。有四个测试用例,后面由(index)引用:
lib.foo
的 try-catch 块,带有一点三角数学。不会抛出任何错误。'foo' in lib
检查函数是否存在,然后调用该函数。typeof lib['foo'] === 'function'
检查函数是否存在,然后调用该函数。Object.prototype.hasOwnProperty.call(lib, 'foo')
检查函数是否存在,然后调用该函数。我在 Chrome 87 上运行了几次基准测试。虽然实际数字不时变化,但结果是一致的,可以粗略总结如下:
澄清一下,慢 75% 意味着如果最快的情况需要 1.0 秒,那么慢 75% 的执行需要 1.75 秒。
总而言之,在永远不会抛出错误的情况下使用 try-catch 似乎与检查任何简单条件一样有效。如果条件更复杂,try-catch 会明显更快。
作为个人笔记,结论与我在大学所教的内容一致。虽然它是在 C++ 的上下文中,但同样的教训似乎也适用于这里。如果我没记错的话,我的讲师说 try-block 的设计非常高效,在效率方面几乎是隐形的。然而,是catch-block 很慢,我的意思是真的很慢。如果抛出错误,那么使用 catch-block 的处理时间比使用 if-else 块所能达到的时间长数百甚至数千倍。因此,保持你的例外例外。