DivideByZeroException太慢了

时间:2010-02-02 11:27:15

标签: c# .net performance exception division

这非常慢:

try
{
    x = k / y;
}
catch (DivideByZeroException) { }

这大约快了5倍:

if (y > 0) x = k / y;

有人可以告诉我为什么吗?

6 个答案:

答案 0 :(得分:11)

只快5倍?你让我感到惊讶。据推测,这意味着您的样本数据中没有很多零。

例外比简单的比较更昂贵。如果使用得当(即在特殊情况下),它们不会显着妨碍性能 - 因为如果你为它做出足够的例外来产生重大影响,那么你的服务很可能已经被软化了。当你使用异常试图忽略你可以很容易地测试开始的条件时, 会导致问题 - 比如这个。

有关异常成本的一点需要注意:它们在调试器中的成本比没有附加调试器的情况下要多得多;特别是需要加载一堆资源的第一个例外可能需要几秒而不是微/毫秒。如果您要对代码进行基准测试,那么在调试器中不这样做是至关重要的 - 这通常是正确的,但特别是对于异常。

答案 1 :(得分:10)

因为例外很昂贵。

当抛出异常时,运行时需要挑出相当多的信息(例如堆栈跟踪)并将它们冒泡。这需要时间和资源,相比之下,0值的测试非常便宜。

请参阅this SO question询问有关更多信息的例外费用。

答案 2 :(得分:5)

错误,因为异常比检查慢。除了简单的if语句之外,例外通常有很多基础设施。

它们不是等效的操作,因为即使您选择不使用,也会在异常中提供大量信息。

答案 3 :(得分:3)

  

为什么异常会变慢?

因为抛出异常时会发生很多事情。有关详细信息,请参阅Chris Brumme's post about the managed exception modelthis post about the underlying Win32 SEH model

  

为什么一个简单的测试很快?

因为它只是根据两个整数的比较结果执行一个跳转指令,这比一个例外要少得多。

  

这是否意味着我应该总是尽量避免例外?

不,这取决于语义。如果除以零是一个您不希望发生的真正异常情况,以及您的程序无法合理处理的情况,那么让异常发生并使您的程序崩溃。但是,如果这是一个预期的案例,并且你可以以合理的方式处理它,那么避免异常似乎是合理的。

答案 4 :(得分:2)

答案 5 :(得分:1)

异常非常慢 - 这就是.Net框架具有TryParse方法的原因:

// This is much quicker...
double result;
if (!double.TryParse("Twelve", out result))
{
    result = -1;
}
return result;

// Than this...
try
{
    return double.Parse("Twelve");
}
catch 
{
    return -1;
}

你应该总是试着避免例外(特殊情况除外 - 哈哈......)