我发现一些旧代码抛出并捕获了一些转换异常(每次约20个 :( )
由此带来的性能影响是什么?我应该担心吗,还是开销只在try / catch中?
令人惊讶的是,在C#中关于异常性能的主题缺乏信息。
谢谢,祝好!
我发现一些旧代码抛出并捕获了一些转换异常(每次约20个 :( )
由此带来的性能影响是什么?我应该担心吗,还是开销只在try / catch中?
令人惊讶的是,在C#中关于异常性能的主题缺乏信息。
谢谢,祝好!
异常会比大部分平均代码行更加拖慢您的进度。不要进行对象转换然后捕获异常,而是使用条件语句来检查。例如:
错误示范
myType foo = (myType)obj;
foo.ExecuteOperation();
好的
myType foo = obj as myType;
if (foo != null)
{
foo.ExecuteOperation();
}
这有两个不好的原因。
如果它们只是try { } finally { }
组,那就没问题了——没有额外的开销。然而,try { } catch { }
既有潜在的危险,也有潜在的缓慢。
编辑:刚刚意识到你说的是捕获“空异常”,而不是“捕获空值异常”。无论如何,除非你正在处理IO,否则出于性能考虑,你可能想避免这样做。
正如其他人所提到的,当抛出异常时会导致性能消耗大。在某些情况下,无法避免使用异常。
然而,在这个情况下,听起来它们绝对可以避免。
我建议在进行强制转换之前使用 as
关键字。这将告诉您强制转换是否成功,从而完全避免异常的发生:
object someObject;
SomeType typedObject;
// fill someObject
typedObject = someObject as SomeType;
if(typedObject == null)
{
// Cast failed
}
if(x is T) y = (T)x;
或者 y = x as T; if(x != null)
结合起来使用。前者也适用于结构体。 - Dykam异常在性能方面是昂贵的。上次我测量时,每个异常抛出和捕获大约需要一毫秒。
避免使用异常作为流程控制机制。
如果您没有遇到任何性能问题,并且这是您执行该算法的唯一方法,请继续使用此方法。
也许在尝试转换之前,您可以使用一些if
语句来查看是否可以进行转换。
int.Parse
将导致创建一个新的异常对象,其中包含整个堆栈的展开。与此同时,int.TryParse
只需要几个时钟周期。另外,我真的想不出一个需要在正常操作中使用异常的算法示例。如果这不是他所询问的正常操作,那么我怀疑他首先就不会提出这个问题--因为显然异常操作是异常的目的。 - Rei Miyasaka