C#强制转换异常
偶然发现一些旧代码正在抛出并捕获一些强制转换异常(每次大约20个:() 如果有任何性能损失是由于这一点造成的呢?我应该担心这一点吗?还是开销只是在尝试/捕获中 令人惊讶的是,缺乏关于C#异常性能主题的信息C#强制转换异常,c#,performance,exception,C#,Performance,Exception,偶然发现一些旧代码正在抛出并捕获一些强制转换异常(每次大约20个:() 如果有任何性能损失是由于这一点造成的呢?我应该担心这一点吗?还是开销只是在尝试/捕获中 令人惊讶的是,缺乏关于C#异常性能主题的信息 非常感谢您的回复。异常非常昂贵,性能也很好。上次我测量这些异常时,它们需要大约一毫秒的时间来抛出和捕获每个异常 避免使用异常作为流控制机制。如果您没有遇到任何性能问题,并且这是您必须执行该算法的唯一方法,请继续使用此方法 可能在尝试强制转换之前,您可以使用一些if子句查看您是否可以执行强制转换
非常感谢您的回复。异常非常昂贵,性能也很好。上次我测量这些异常时,它们需要大约一毫秒的时间来抛出和捕获每个异常
避免使用异常作为流控制机制。如果您没有遇到任何性能问题,并且这是您必须执行该算法的唯一方法,请继续使用此方法
可能在尝试强制转换之前,您可以使用一些
if
子句查看您是否可以执行强制转换。正如其他人所提到的,异常在抛出时代价高昂。在某些情况下,它们是无法避免的
不过,在这种情况下,听起来他们肯定可以
我建议在强制转换之前使用作为
关键字。这将告诉您强制转换是否成功,从而完全避免异常:
object someObject;
SomeType typedObject;
// fill someObject
typedObject = someObject as SomeType;
if(typedObject == null)
{
// Cast failed
}
异常将使您的速度比大多数平均代码行慢得多。与其强制转换然后捕获异常,不如进行检查。例如 坏的
myType foo = (myType)obj;
foo.ExecuteOperation();
myType foo = obj as myType;
if (foo != null)
{
foo.ExecuteOperation();
}
好
myType foo = (myType)obj;
foo.ExecuteOperation();
myType foo = obj as myType;
if (foo != null)
{
foo.ExecuteOperation();
}
这不好有两个原因
try{}finally{}
组,那么一切都很好——没有开销。然而,try{}catch{}
既有潜在的危险,也有潜在的缓慢
至于文档,这非常好:
编辑:刚刚意识到你说的是捕获空异常,而不是捕获空异常。不管怎样,除非你是在处理IO,否则你可能会为了性能而避免这样做。异常是昂贵的。在正常操作中使用它们是不好的做法。我从来没有说过它们不昂贵。如果你读了我的帖子,我已经写了注意,只有在他没有发现性能问题或者这是编写算法的唯一方法的情况下,他才能使用它。这里的操作表达式是“如果……这是执行算法的唯一方法。”有时,你必须打破规则。这并不难看,但这是事实。虽然我可能会重构这样的代码以使用TryParse,但问题仍然存在:如果它失败了,你该怎么办?例如,如果你正在编写一个程序来解析大量数据,其中一些可能是整数,使用
int.parse
将导致新的异常要创建的对象,包含整个堆栈的展开。同时,int.TryParse
将只需要几个时钟周期。此外,老实说,我不能给出一个算法示例,要求在正常操作中使用异常。如果这不是他问的正常操作,那么我怀疑他是否会ave首先提出了这个问题,因为异常操作显然就是异常的用途。有相当数量的第三方库在内部执行大量“流控制异常”。如何检查文件是否存在?打开文件,看看它是否失败!在这种情况下,直接检查文件是否存在没有多大帮助,因为它可能在您使用它之前就不存在了,但在您检查之后就不存在了。因此,在某些情况下,会出现异常,并将其用作流控制机制。他是否应该处理ex异常,只是不是通过抛出异常,他可以优雅地处理它。任何他无法优雅地捕获的异常都是您希望在发生时抛出的异常类型,如果他小心,它们当然不应该发生。如果(x是t)y=(t)x;或y=x作为t;如果(x!=null),则应该组合if(x是t)y=(t)x;
或y=x作为t;if(x!=null)
。前者也适用于结构。最终发现方法本身的本质存在问题,并将一个30行的显式强制转换转化为两行代码,从3.8秒(10000项)到3毫秒。谢谢大家!