我想知道,在一般编程中哪些更好或更快?避免异常或等待异常?
避免例外:
string a = null;
list = someMethod();
if(list.Length > 0 ){
a = list[0];
}
if(a!=null) ...
或尝试捕获异常......
string a = null;
try{
a = someMethod()[0];
catch{}
if(a!=null) ...
答案 0 :(得分:19)
性能不是这里最关注的问题。问题是,两者中的哪一个导致更易读/可维护/可测试的程序。您可以稍后担心性能。
通常,不要使用流量控制的异常。它们实际上是非本地的goto
,这使得程序更难以阅读和遵循。因此,它们应该保留用于特殊情况。如果您可以不使用try-catch
块进行流量控制,请不要这样做。您的程序将更具可读性和可维护性。
处理这种情况的“正确”方法是
var list = someMethod();
if(list == null || list.Length == 0) {
// handle something bad
}
string a = list[0];
if(a != null) {
// go
}
如果存在保证list
的返回值不为空且非空的合同(Contract.Ensures
),则可以避免检查someMethod
不为空且不为空。
然而,异常在当地很昂贵。它们是否会影响程序的性能(即瓶颈)是另一个问题。但是如果使用得当,异常通常不是瓶颈(当应用程序崩溃时谁会关心性能?)
答案 1 :(得分:8)
例外是昂贵的 - 如果你可以测试并避免例外,那就这样做。
不应将异常用于正常的程序流程。
答案 2 :(得分:3)
当然要避免异常,尝试捕获会导致丢失性能。
答案 3 :(得分:2)
这取决于。 我几乎总是试图避免异常,除非这样做成本太高。
答案 4 :(得分:1)
纯粹从大量N指令运行时的指令/性能角度来看,避免更昂贵,因为每次输入时都要检查长度。除了例外,catch
分支仅在该可能性上执行。
答案 5 :(得分:0)
如果可以的话,总是始终避免例外。
例外应该是例外。
如果你能预测它,就要防止它发生。
应该禁止使用这类空挡块的人使用计算机......
不进入捕获区也更快。
答案 6 :(得分:0)
抛出异常是一项昂贵的任务,因此我总是尝试验证而不是捕获。
这应该很容易测试,生成一些代码,通过每次运行抛出异常,并针对一组类似的代码进行测试,这些代码执行条件检查并测量性能。
如果代码中记录了将抛出异常条件的详细信息,那么您应该能够调整您的调用代码。当然,您无法处理每个场景(可能是较低级别的运行时错误?),因此您的代码应该只是真正尝试并处理可以实际响应并可能继续的异常。
答案 7 :(得分:0)
异常只应用于特殊情况(除非没有其他选择),所以你应该只使用try / catch,当你仍然需要处理非常不寻常的事情时(弹出错误信息)。
尝试/ catch也向程序员发出信号,表明可能会发生某些外部错误并需要处理。在您的示例中,list
为null只是程序执行/控制流程的正常部分,因此没有什么特别之处。
此外,无论如何,一个空的通用都是一件坏事(尽管在需要时情况有限)。无论如何,它肯定需要一个评论来解释为什么你没有对异常做任何事情。
有一个useful blog post关于你可能会觉得有用的虚假异常