7

这非常慢:

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

这大约快 5 倍:

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

谁能告诉我为什么?

4

6 回答 6

11

只快5倍?你真让我吃惊。大概这意味着您的样本数据中没有很多零。

异常比简单的比较更昂贵。如果使用得当(即在特殊情况下),它们往往不会显着影响性能——因为如果您抛出足够多的异常以产生重大影响,那么您的服务很可能已经被破坏了。当您使用异常尝试忽略您可以很容易地测试开始的条件时,它确实会导致问题 - 就像这个。

关于异常成本需要注意的一件事:它们在调试器中的成本比在没有附加调试器的情况下运行时要高得多;特别是需要加载一堆资源的第一个异常可能需要几秒钟而不是微/毫秒。如果您要对代码进行基准测试,请务必不要在调试器中执行它——这通常是正确的,但特别是对于异常。

于 2010-02-02T11:30:58.617 回答
10

因为异常是昂贵的。

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

有关更多信息,请参阅此 SO 问题,询问例外情况有多昂贵。

于 2010-02-02T11:28:32.403 回答
5

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

它们不是等效的操作,因为即使您选择不像在这种情况下那样使用它,也会在异常中传递大量信息。

于 2010-02-02T11:30:05.880 回答
3

为什么异常很慢?

因为当抛出和捕获异常时会发生很多事情。有关详细信息,请参阅Chris Brumme 关于托管异常模型的文章和关于底层 Win32 SEH 模型的这篇文章。

为什么简单的测试很快?

因为它只是根据两个整数的比较结果执行一条指令跳转,这比异常工作少得多。

这是否意味着我应该始终尽量避免异常?

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

于 2010-02-02T11:31:00.707 回答
2

看看这篇文章:

于 2010-02-02T11:32:45.920 回答
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;
}

你应该总是尽量避免例外(除非在特殊情况下 - 哈哈......)

于 2010-02-02T11:34:21.027 回答