一个try/catch块的性能代价

13

可能重复:
‘try’的性能成本

有人告诉我,在一个包含一百万次循环的例子中,添加try catch块会使程序运行速度慢1000倍。这是真的吗?

使用尽可能多的try catch块难道不是最好的选择吗?


https://dev59.com/eXVC5IYBdhLWcg3w2lCI为什么try块很耗费资源?https://dev59.com/PnI95IYBdhLWcg3w-C9btry-catch块总是很耗费资源吗? - Greg
2
请先搜索,然后复制很多很多遍。 - Craig Stuntz
2
可能是它们中最好的副本:https://dev59.com/SnM_5IYBdhLWcg3wmkYK - x4u
我搜索了try catch块的成本,但没有找到任何相关的内容,甚至提供了类似的主题,但都不相关。 - GenEric35
7个回答

36

来自MSDN网站

减少异常处理代码可以提高性能。请注意,这与try/catch块无关:只有在实际抛出异常时才会产生代价。您可以使用任意数量的try/catch块。使用异常处理不当会降低性能。例如,应避免将异常处理用于控制流程。

另请参阅以下相关问题:(1) (2) (3)(4)


11

我记得就在几天前似乎有一个类似的问题,但我找不到它了...

只是添加一个 try/catch 块通常不会明显改变性能,除非没有抛出异常,虽然它可能会防止方法被内联。 (不同版本的 CLR 在内联方面有不同的规则;我记不清楚细节了。)

真正的开销是在实际抛出异常时 - 即使这个开销通常是夸大的。如果你适当地使用异常(即仅在真正异常或意外错误情况下使用),那么除了在服务太过于混乱而无法被认为是“正常工作”之外,它们不太可能对性能造成重大影响。

至于是否应尽可能使用 try/catch 块 - 绝对不!通常只有在您实际可以处理异常时才应该捕获异常 - 这相当罕见。特别是,仅仅吞咽一个异常几乎总是错误的做法。

我编写的 try/finally 块比 try/catch 块要多得多(实际上几乎总是通过 using 语句)。在堆栈的顶层使用 Try/catch 有时是合适的,以便服务即使失败一个请求也可以继续处理下一个请求,但除此之外,我很少捕获异常。有时候值得捕获一个异常以将其包装在另一个异常中 - 基本上是翻译异常而不是真正处理它。


2
相对来说比较罕见吧?所以如果打开一个不存在的文件会崩溃应用程序?如果收到404错误会崩溃应用程序?如果将没有数字的字符串转换为数字会崩溃应用程序?我认为,除非程序无法恢复,否则就让它崩溃。但是,如果你能够恢复,那不是更好吗? - Toad
3
如果您要将字符串转换为数字,应该使用TryParse(如果这是用户输入的话)。但重要的是,大多数情况下,这些问题应该在相对较高的层次上解决(如果需要解决)。这对于客户端应用程序比服务器端应用程序更难,但请注意问题标签 - OP从ASP.NET的角度进行讨论。通常,如果出现异常,正确的方法是中止请求并向用户报告错误。这需要多少个catch块? - Jon Skeet

3

您绝对应该测试这样的声明(这很容易),但不,这不会伤害您(它会有成本,但不是1000倍)。

抛出异常并处理它们是昂贵的。使用try..catch..finally并不糟糕。

现在说到这一点,如果您要捕获异常,您需要计划如何处理它。如果您只是要重新抛出异常,则捕获异常没有意义,而且很多时候,如果出现异常,您无法做太多事情。


1

添加try catch块有助于控制您无法控制的异常。性能成本来自在存在其他替代方案时抛出异常。例如,为了退出例程而抛出异常而不是简单地从例程返回会导致大量开销,这可能完全是不必要的。


0

我被告知添加try catch块会导致性能成本大约比没有慢1000倍,例如在一百万次循环中。这是真的吗?

使用try catch确实会增加性能成本,但它并不是一个重大的性能成本。

最好尽可能地使用try catch块吗?

不是的,最好在有意义的情况下使用try catch块。


性能成本取决于您使用的编译器。 - Zachary Vance

0
为什么要猜测性能成本,当你可以进行基准测试并查看其是否重要呢?


0

确实,异常是一项非常昂贵的操作。同时,try..catch块会使代码凌乱并且难以阅读。尽管如此,大多数时候,异常适合用于应该崩溃应用程序的错误。

我总是在所有异常上运行断点,所以一旦出现错误,它就会抛出,并且我可以相对容易地定位问题。如果每个人都一直抛出异常,那么程序性能就会变差,我无法使用所有异常断点,这让我很难过。

在我看来,不要将异常用于正常的程序事件(例如用户输入了一个非数字,而您尝试将其解析为数字)。对于这种情况,请使用正常的程序流控制结构(即if)。

如果您使用可能引发异常的函数,那么您需要作出选择。如果错误很关键,则崩溃应用程序。如果错误非关键且可能发生,则捕获它(并潜在地记录它)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接