Java try / catch性能,是否建议将try子句中的内容保持在最低限度?

时间:2010-11-25 21:01:28

标签: java performance try-catch readability

考虑到你有这样的代码:

doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.

现在我知道,构造异常时实际上会遇到性能损失,特别是展开堆栈。我还阅读了几篇文章,指出在输入try / catch块时会有轻微的性能损失,但这些文章似乎都没有结论。

我的问题是,是否建议将try catch中的行保持最小?,即只在try子句中包含可以实际抛出正在捕获的异常的行。 try子句中的代码运行速度较慢或导致性能下降吗?。

但考虑到这一点,更重要的是最佳实践/更易读的解决方案:

try {
    doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.
}
catch (MyCheckedException e) {
   //handle it
}

或:

try {
    doSomething() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
   //Store my exception in a Map (this is all running in a loop and I want it to   continue running, but I also want to know which loops didn't complete and why)
   continue;     
} 
 //do some assignements calculations
try {
    doAnotherThing() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
    //Store my exception in a Map (this is all running in a loop and I want it to   continue running, but I also want to know which loops didn't complete and why)
   continue;
} 

考虑到你将以完全相同的方式处理所有这些已检查的异常。

9 个答案:

答案 0 :(得分:23)

  

建议保留线条   在try catch里面到最低限度?

没有。无法想象你怎么能认为try块的长度或任何块的长度都会对性能产生任何影响。

  

try子句中的代码   运行速度较慢或导致任何性能   击中?

没有

正如您所观察到的,异常只会在投掷时产生性能成本。

如果您担心“尝试”表现,当然要做的是将代码保持在最大值?

答案 1 :(得分:15)

在这里的示例中,真正的性能影响是doSomething()和doAnotherThing()都抛出异常。输入try-block很快,直到它抛出异常。

这真的取决于你的情况。如果你在任何方式抛出MyCheckedException时都需要做同样的事情,我认为将它们放在同一个try块中更具可读性和更高性能,但如果你需要以不同的方式处理两种不同的情况,那么当然将它们分开是更有意义的。

编辑:我看了你的评论的结尾,你假设处理方式相同,在这种情况下,我将它们放在同一个试块中。

答案 2 :(得分:4)

我不确定哪一个更慢,但不要忘记try块是控制流。您应该使控制流符合您要完成的任务。对我来说,选择

try {
    // op 1.
    // op 2.
    / ...
    // op n.
}
catch ( MyCheckedException error )
{
    // handle any `MyException` in op 1, 2 ... n.
}
每个

和单独的catch块主要决定我是否要为每个操作执行不同的处理,不管错误如何都继续执行直到op n或尝试执行所有操作并失败在第一次错误。

编写干净,可读的代码,然后搜索瓶颈。如果现有的实验不能得出基本指南的结论,那么我怀疑这不是你会发现瓶颈的地方。

答案 3 :(得分:3)

尝试块在任何体面的JVM中应该基本上没有性能影响。真正的打击是在实际抛出异常时发生的。

您可以阅读this article以了解JVM如何在字节码中实现异常处理:它创建“异常表”,将代码区域映射到catch / finally块,因此:

  • try-block的字节代码与标准{}块
  • 相同
  • 非抛出案例中唯一的额外费用是将“异常表”加载到内存中。

当然,当抛出异常时,会有大量的堆栈工作正在进行,因此会产生成本。无论如何,它几乎没有SEH(.NET例外)那么糟糕。

答案 4 :(得分:2)

您的代码应该只处理它可以执行某些操作的异常,其他代码应该重新抛出。

try块中的代码量不会导致速度减慢,但是遇到catch块。但除非您尝试编写真正的高性能代码,否则我不会担心它。

答案 5 :(得分:1)

将try / catch块的数量保持在最低限度可以略微提高性能,但是移动工作并不会产生任何影响,除了因抛出异常而跳过的工作。

答案 6 :(得分:0)

每个异常块都有开销。所以,你想要最大化你在一个街区停留的时间。

但是,您还必须考虑语义上的差异。在第一个示例中,如果doSomething()抛出异常,则不会运行doAnotherThing()。在第二个示例中(假设catch处理程序未返回),将运行doAnotherThing()

答案 7 :(得分:0)

我不确定try块内部的性能可能会很慢,但我所知道的是ex.getStackTrace()的性能非常慢,因为它显示了所有的命令堆栈和你应该小心。

答案 8 :(得分:0)

异常花费很多,因为每次抛出异常时,都必须创建并填充堆栈跟踪。

想象一下,由于缺乏资金,1%的案件失败了余额转移操作。 即使失败率相对较低,性能也可能受到严重影响。

请参阅源代码和基准测试结果here