关于c#:.NET try / catch是否便宜?

Are .NET try / catch cheap?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Performance Cost Of 'try'

我在msdn的"处理异常的最佳实践"中偶然发现了这句话:

"使用异常处理更好,因为在正常情况下执行的代码更少"

在调用方法之前,应该检查对象的状态,还是只调用方法并捕获异常。上述建议适用于例外情况很少发生的情况。

假设属性检查不意味着昂贵的计算,而只是返回一个状态值,那么与属性检查相比,非抛出情况下的try/catch块的执行成本有多低?

我想知道这个建议,因为即使try/catch是免费的或接近免费的,被调用的方法在许多情况下也会自己进行一系列检查。


.NET中的异常非常便宜,除非提出。一旦你提出一个例外,有效成本就会上升很多。

这就是说,我强烈建议在这里使用最可维护的解决方案进行编程,并在以后担心性能,如果,并且仅当,它在测量之后被证明是一个问题时。

一个只返回状态的属性get方法被优化为字段查找,并且几乎是一个单一的操作——任何操作通常都会比以后慢。但是,我怀疑异常处理会对您的整体速度产生任何明显的影响,除非它处于非常、非常紧密的循环中——在这种情况下,整体性能可能不会比您为避免异常处理而引入的检查更差。


你在断章取义。完整的引用是(强调我的):

If the event is truly exceptional and
is an error (such as an unexpected
end-of-file), using exception handling
is better because less code is
executed in the normal case. If the
event happens routinely, using the
programmatic method to check for
errors is better. In this case, if an
exception occurs, the exception will
take longer to handle.

异常处理的开销来自实际捕获异常。如果一个异常没有被抛出/捕获,那就相对便宜了。

上述报价的逻辑如下:

  • 如果您多次重复该操作,并且发生异常是不合理的,那么不要执行检查,使用异常。您通过不重复每次迭代的检查来保存代码周期。

  • 如果操作不反复循环,则检查条件而不是捕获异常。

第一点可以被视为过早优化的情况,但这一点是有效的,但是,它应该只适用于例外情况(没有双关语的意图)。

通常,您将希望按照本文的建议进行操作,并对照某些状态进行检查,而不是依赖异常处理。


使用Try/Catch的另一个好处是,它允许您将错误处理集中在一个块中,特别是当函数中存在可能引发异常的多个原因时。如果您不需要以不同的方式处理每种情况,那么对所有这些调用都进行一次尝试/捕获是有意义的,这样可以集中处理异常。

更重要的是,它允许您最终使用,这对于确保正确清理资源非常有效,无论是否引发异常。


"例外情况适用于例外情况",不适用于正常控制流。

例如,当您在一个循环中捕获数千个异常时,IME、C异常会增加明显的性能损失。


通常,异常处理机制的设计意图是尝试是便宜的,抛出是昂贵的。但是,例外情况肯定比大多数其他操作更昂贵。尽可能避免抛出是最具性能的解决方案,如果您可以使用一个简单的if语句而不是使用异常,那么就应该这样做。