当没有抛出异常时,C ++异常以什么方式减慢代码?

时间:2009-12-13 22:03:55

标签: c++ exception overhead

我已经读过,使用C ++异常进行异常处理会有一些开销,而不是检查返回值。我只是谈论没有抛出异常时产生的开销。我还假设您需要实现实际检查返回值的代码并执行适当的操作,无论它与catch块的作用相同。并且,将异常对象与内部45个状态变量抛出的代码与为每个错误返回负整数的代码进行比较也是不公平的。

我不是仅仅基于哪一个可以更快地执行来构建支持或反对C ++异常的案例。我听说最近有人提出这样的情况:一旦你考虑了检查返回值和处理错误所需的所有额外簿记代码,使用异常的代码应该像基于返回代码的代码一样快。我错过了什么?

6 个答案:

答案 0 :(得分:46)

某些平台和某些编译器的异常处理相关成本。

即,Visual Studio在构建32位目标时,将在每个具有非平凡析构函数的局部变量的函数中注册一个处理程序。基本上,它设置了try/finally处理程序。

gcc和Visual Studio以64位为目标的另一种技术只会在抛出异常时产生开销(该技术涉及遍历调用堆栈和表查找)。在很少抛出异常的情况下,这实际上可以导致更高效的代码,因为不必处理错误代码。

答案 1 :(得分:11)

只有try / catch和try / except块才能设置一些指令。除了最迂回的环路之外,在每种情况下,开销通常应该可以忽略不计。但是你通常不会在内循环中使用try / catch / except。

我建议不要担心这一点,而是使用分析器代替在需要时优化代码。

答案 2 :(得分:8)

它完全依赖于实现,但是当没有抛出异常时,许多最近的实现几乎没有或没有性能开销。事实上你是对的。正确地检查代码中不使用异常的所有函数的返回代码可能会慢,然后对使用异常的代码不做任何操作。

当然,您需要根据您的特定要求来衡量性能。

答案 3 :(得分:0)

有一些例外的开销(正如其他答案所指出的那样)。

但是现在你没有多少选择。尝试在项目中禁用异常,并确保所有相关代码和库可以在没有编译和运行的情况下运行。

它们是否可以禁用例外?

让我们假设他们这样做!然后对某些情况进行基准测试,但请注意,您必须设置“禁用异常”编译开关。如果没有那个开关,你仍然会有开销 - 即使代码永远不会抛出异常。

答案 4 :(得分:-1)

只有开销是~6条指令,它们在函数开始时添加2个SEH并将它们留在最后。无论你在一个线程中有多少尝试/捕获,它总是一样的。

这又是关于局部变量的呢?我听说人们在使用try / catch时总是抱怨他们。我不明白,因为解构者最终会被调用。此外,你不应该让一个例外超过1-3个电话。

答案 5 :(得分:-4)

我使用了Chip Uni的测试代码并对其进行了扩展。我将代码分成两个源文件(一个有例外;一个没有)。我将每个基准测试运行1000次,并使用clock_gettime()CLOCK_REALTIME来记录每次迭代的开始和结束时间。然后我计算了数据的均值和方差。我使用64位版本的g ++ 5.2.0和clang ++ 3.7.0在带有16GB RAM的Intel Core i7盒上运行此测试,该内存使用内核4.2.5-1-ARCH运行ArchLinux。您可以找到扩展代码和完整结果here

克++

没有例外
  • 平均值:30,022,994纳秒
  • 标准偏差:1.25327e + 06纳秒
例外
  • 平均值:30,025,642纳秒
  • 标准偏差:1.83422e + 06纳秒

铛++

没有例外
  • 平均值:20,954,657纳秒
  • 标准偏差:426,662纳秒
例外
  • 平均值:23,916,638纳秒
  • 标准偏差:1.72583e + 06纳秒

C ++异常只会对clang ++产生一个非常重要的性能损失,即使这个惩罚只有~14%。