DivideByZeroException 太慢

发布于 2024-08-20 03:30:17 字数 185 浏览 2 评论 0原文

这非常慢:

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

这大约快了 5 倍:

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

有人能告诉我为什么吗?

This is extremely slow:

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

This is about 5x faster:

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

Can anybody tell me why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

野生奥特曼 2024-08-27 03:30:17

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

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

关于异常成本需要注意的一件事:它们在调试器中的成本比在不附加调试器的情况下运行时的成本高得多;特别是需要加载一堆资源的第一个异常可能需要几秒而不是微/毫秒。如果您要对代码进行基准测试,那么不要在调试器中执行此操作至关重要 - 一般来说确实如此,但对于异常情况尤其如此。

Only 5 times faster? You do surprise me. Presumably that means your sample data doesn't have many zeroes in it.

Exceptions are more expensive than simple comparisons. When used correctly (i.e. for exceptional circumstances) they don't tend to hamper performance significantly - because if you're throwing enough exceptions for it to make a big impact, chances are your service is already hosed. It does cause a problem when you use exceptions to try to ignore conditions which you could very easily test to start with - like this one.

One thing to note about the cost of exceptions: they cost a lot more in the debugger than when running without a debugger attached; in particular the first exception which needs to load a bunch of resources can take seconds rather than micro/milliseconds. If you're going to benchmark code, it's vital that you don't do it in a debugger - that's true in general, but particularly for exceptions.

剪不断理还乱 2024-08-27 03:30:17

因为例外是昂贵的。

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

有关详细信息,请参阅这个问题询问异常的成本如何。

Because exceptions are expensive.

When an exception is thrown, the runtime needs to pick out quite a lot of information (stack traces for example) and bubble them up. This takes time and resources, when a test for 0 value is very cheap in comparison.

See this SO question asking how expensive exceptions are for more info.

赢得她心 2024-08-27 03:30:17

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

它们不是等效的操作,因为您在异常中传递了很多信息,即使您选择不使用它(如本例所示)。

Err, because exceptions are slower than checking. Exceptions generally have a lot lot of infrastructure around them that a simple if statement doesn't.

They're not equivalent operations since you have a lot of information delivered in an exception even if you choose not to use it as in this case.

雨轻弹 2024-08-27 03:30:17

为什么异常很慢?

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

为什么简单的测试会很快?

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

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

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

Why are exceptions slow?

Because a lot of stuff happens when an exception is thrown and caught. See Chris Brumme's post about the managed exception model and this post about the underlying Win32 SEH model for details.

Why is a simple test fast?

Because it just executes one instruction to jump depending on the result of the comparison of two integers which is much less work than an exception.

Does that mean I should always try to avoid exceptions?

No, it depends on semantics. If dividing by zero is a truly exception case that you do not expect to happen, and which your program cannot reasonably handle, then let the exception occur and crash your program. If, however, it's an expected case and you can handle it in a reasonable way then it would seem reasonable to avoid the exception.

情域 2024-08-27 03:30:17

异常非常慢 - 这就是 .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;
}

您应该始终尝试避免异常(例外情况除外 - 哈哈...)

Exceptions are extremely slow - This is the reason that the .Net framework has TryParse methods:

// 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;
}

you should always try and avoid exceptions (except for in exceptional circumstances - haha...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文