简体   繁体   English

什么更好/更快? 尝试捕获还是避免异常?

[英]What's better/faster? Try-catch or avoid exception?

I would like to know, what's better or/and faster in general programming? 我想知道,在一般编程中哪个更好或更快速? Avoid the exception or wait for the exception? 避免例外还是等待例外?

Avoid the exception would be: 避免出现以下异常:

string a = null;
list = someMethod();
if(list.Length > 0 ){
   a = list[0];
}
if(a!=null) ...

Or try catch exception... 或者尝试捕获异常...

string a = null;
try{
    a = someMethod()[0];
catch{}
if(a!=null) ...

Performance is not the most relevant concern here. 在这里,性能并不是最相关的问题。 The question is, which of the two leads to more readable/maintainable/testable programs. 问题是,哪两个导致程序更易读/可维护/可测试。 You can worry about performance later. 您稍后可以担心性能。

In general, don't use exceptions for flow control. 通常,请勿将异常用于流控制。 They are effectively a non-local goto which makes programs more difficult to read and follow. 它们实际上是非本地的goto ,这使得程序更难以阅读和遵循。 As such, they should be reserved for exceptional situations. 因此,它们应保留用于特殊情况。 If you can get away with not using a try-catch block for flow control, don't. 如果您可以不使用try-catch块进行流控制而摆脱困境,那就不要。 Your programs will be more readable and maintainable. 您的程序将更具可读性和可维护性。

The "right" way to handle this situation is 处理这种情况的“正确”方法是

var list = someMethod();
if(list == null || list.Length == 0) {
    // handle something bad
}
string a = list[0];
if(a != null) {
    // go
}

You can avoid the check that list is not null and not empty if there is a contract ( Contract.Ensures ) that guarantees the return value from someMethod is not null and not empty. 如果存在一个保证someMethod返回值不为null且不为空的合同( Contract.Ensures ),则可以避免检查list是否为null且不为空。

It is true, however, that exceptions are locally expensive. 但是,确实如此,例外在本地昂贵。 Whether or not they will impact the performance of your program (ie, are a bottleneck) is another question altogether. 它们是否会影响程序的性能(即成为瓶颈)还是另一个问题。 But used properly, exceptions are generally not a bottleneck (who cares about performance when your application is crashing?) 但是使用得当,异常通常不是瓶颈(谁在乎您的应用程序崩溃时关心性能?)

Exceptions are expensive - if you can test and avoid the exception, do so. 异常的代价很高-如果您可以测试并避免异常,请这样做。

Exceptions should not be used for normal program flow. 正常程序流程不应使用异常。

当然要避免异常,尝试捕获会导致性能下降。

It depends. 这取决于。 I almost always try to avoid the exception unless doing so is prohibitively costly. 我几乎总是尝试避免例外,除非这样做的代价太高了。

Purely from a number of instructions / performance standpoint over a significant N runtime, avoiding is more expensive, because you're checking the length every time for every input. 纯粹从大量N运行时的大量指令/性能角度出发,避免开销更大,因为您要每次检查每个输入的长度。 With an exception, the catch branch is only executed on that eventuality. 除了例外,仅在这种情况下执行catch分支。

ALWAYS ALWAYS ALWAYS avoid an exception if you can. 如果可以,请始终避免出现异常。

Exceptions should be exceptional. 例外应该是例外。

If you can predict it, protect against it happening. 如果可以预测,请防止发生。

People who use empty catch blocks like that should be banned from using a computer... 应该禁止使用空的捕获块的人使用计算机。

It's also faster to not go into catch blocks. 不陷入困境也更快。

Throwing exceptions is an expensive task, so I would always try and validate rather than catch. 抛出异常是一项昂贵的任务,因此我将始终尝试并验证而不是捕获。

This should be easy enough to test, generate some code that throws an exception through each run and test it against a similar set of code that does conditional checking and measure the performance. 这应该很容易测试,生成一些在每次运行时都会引发异常的代码,并针对一组类似的,进行条件检查和衡量性能的代码进行测试。

If the code is documented with details of which conditions exceptions will be thrown, you should be able to adapt your calling code. 如果代码中记录了将引发异常的详细信息,则您应该能够调整您的调用代码。 Of course you can't handle every scenario (lower level runtime errors perhaps?), so your code should only really try and handle exceptions where it can actually react and possibly continue. 当然,您不能处理所有情况(可能是较低级别的运行时错误?),因此您的代码应该只真正尝试并处理可能实际响应并可能继续的异常。

Exceptions should only be used for exceptional conditions (unless there's no alternative), so you should only use try/catch when there's something highly unusual going on that you still need to deal with (pop up an error message). 异常仅应用于特殊情况(除非没有其他选择),因此仅应在仍然需要处理非常异常的事件(弹出错误消息)时才使用try / catch。

Having a try/catch also signals to a programmer that some external error might happen and needs to be dealt with. 尝试/捕获还会向程序员发出信号,表明可能发生某些外部错误,需要进行处理。 In your example, list being null is simply a normal part of program execution/control flow, and so there's nothing exceptional about it. 在您的示例中, list为null只是程序执行/控制流程的正常部分,因此没有什么例外。

Also, an empty catch-all is generally a bad thing to have anyway (although there are limited situations where it's needed). 同样,空包总之无论如何通常都是不好的事情(尽管在某些情况下需要使用它)。 It should certainly need a comment anyway to explain why you're not doing anything about the exceptions. 无论如何,它肯定应该需要注释以解释为什么您不对异常做任何事情。

There's a useful blog post about vexing exception you might find useful 关于有用的异常,有一篇有用的博客文章 ,您可能会觉得有用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM