当没有任何异常抛出时,使用多个try-catch块是否“缓慢”?我的问题与这一问题相同,但对于JavaScript。
假设我有20个在其中具有try-catch块的函数,以及另一个函数,在这20个函数中的每个函数都调用时,它们都不抛出异常。由于有try-catch块,我的代码执行速度会变慢还是变差?
当没有任何异常抛出时,使用多个try-catch块是否“缓慢”?我的问题与这一问题相同,但对于JavaScript。
假设我有20个在其中具有try-catch块的函数,以及另一个函数,在这20个函数中的每个函数都调用时,它们都不抛出异常。由于有try-catch块,我的代码执行速度会变慢还是变差?
try
可以忽略不计,但这取决于您对的定义slow
。如果您正在寻找性能,那么还有更多更好的选择try/catch
。@Roland很好地列出了一些不使用它们的充分理由。
Answers:
您在执行典型的CRUD UI代码吗?使用try catch,无缘无故地使用循环到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
与普通代码相同。
最初的问题询问未抛出错误时尝试/捕获的成本。使用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基本上是零惩罚。
该try-catch
块被认为是昂贵的。但是,如果关键性能不是问题,那么使用它就不必担心。
IMO的罚款为:
可读性:使用大量的try-catch来检查代码很丑陋,分散注意力
不适当的:如果您的代码没有发生异常崩溃,则插入这样的块是一个坏主意。仅当您期望代码失败时才插入它。看一下以下主题:何时使用try / catch块?
异步:该try-catch
块是同步的,在async
编程时无效。在ajax
请求期间,您可以在专用回调中处理error
和success
事件。不需要try-catch
。
希望这可以帮助,
R.
catch
不会出现在块中。await
通过承诺链尝试/捕获与错误处理相比,还有明显的优势,但这超出了本文的范围。有关更多信息:gist.github.com/mikermcneil/c1028d000cc0cc8bce995a2a82b29245
我尝试根据具体的基准测试结果提供答案。为此,我编写了一个简单的基准,将尝试捕获与从简单到更复杂的各种if-else条件进行了比较。我知道基准可能会因平台而发生很大变化。如果您得到不同的结果,请发表评论。请参阅此处的try-catch基准。
首先,我尝试以一种紧凑的方式在这里表示测试套件。有关完整的详细信息,请参见上面的链接。有四个测试用例,稍后由(索引)引用:
lib.foo
使用一些三角函数调用函数。不会抛出任何错误。'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 ++的上下文中,但此处也适用相同的课程。如果我没记错的话,我的讲师说试块的设计非常高效,几乎是看不见的。但是,这是一个很慢的陷阱,我的意思是真的很慢。如果抛出错误,则使用catch块进行处理的时间要比使用if-else块所完成的处理时间长数百倍甚至数千倍。因此,请保持例外情况例外。