C++ 有哪些方式?当没有抛出异常时,异常会减慢代码速度吗?
我读到,使用 C++ 异常进行异常处理(而不是检查返回值)会产生一些开销。我只是谈论没有抛出异常时产生的开销。我还假设您需要实现实际检查返回值并执行适当操作的代码,无论什么都相当于 catch 块将执行的操作。而且,将抛出内部有 45 个状态变量的异常对象的代码与为每个错误返回负整数的代码进行比较也是不公平的。
我并不是试图仅仅根据哪个可能执行得更快来建立支持或反对 C++ 异常的案例。我听说最近有人提出这样的情况:一旦考虑到检查返回值和处理错误所需的所有额外簿记代码,使用异常的代码应该与基于返回代码的代码运行得一样快。我缺少什么?
I have read that there is some overhead to using C++ exceptions for exception handling as opposed to, say, checking return values. I'm only talking about overhead that is incurred when no exception is thrown. I'm also assuming that you would need to implement the code that actually checks the return value and does the appropriate thing, whatever would be the equivalent to what the catch block would have done. And, it's also not fair to compare code that throws exception objects with 45 state variables inside to code that returns a negative integer for every error.
I'm not trying to build a case for or against C++ exceptions solely based on which one might execute faster. I heard someone make the case recently that code using exceptions ought to run just as fast as code based on return codes, once you take into account all the extra bookkeeping code that would be needed to check the return values and handle the errors. What am I missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
某些平台和某些编译器上的异常处理会产生相关成本。
也就是说,Visual Studio 在构建 32 位目标时,将在每个具有非平凡析构函数的局部变量的函数中注册一个处理程序。基本上,它设置了一个 try/finally 处理程序。
另一种技术由面向 64 位的 gcc 和 Visual Studio 使用,仅在抛出异常时才会产生开销(该技术涉及遍历调用堆栈和表查找)。在很少抛出异常的情况下,这实际上可以产生更高效的代码,因为不需要处理错误代码。
There is a cost associated with exception handling on some platforms and with some compilers.
Namely, Visual Studio, when building a 32-bit target, will register a handler in every function that has local variables with non-trivial destructor. Basically, it sets up a
try/finally
handler.The other technique, employed by
gcc
and Visual Studio targeting 64-bits, only incurs overhead when an exception is thrown (the technique involves traversing the call stack and table lookup). In cases where exceptions are rarely thrown, this can actually lead to a more efficient code, as error codes don't have to be processed.只有 try/catch 和 try/ except 块需要一些指令来设置。除了最紧密的循环之外,在每种情况下,开销通常都可以忽略不计。但无论如何,您通常不会在内循环中使用 try/catch/ except 。
我建议不要担心这个,并在需要时使用分析器来优化您的代码。
Only try/catch and try/except block take a few instructions to set up. The overhead should generally be negligible in every case except the tighest loops. But you wouldn't normally use try/catch/except in an inner loop anyway.
I would advise not to worry about this, and use a profiler instead to optimize your code where needed.
它完全依赖于实现,但许多最近的实现在不引发异常时几乎没有或没有性能开销。事实上你是对的。正确检查不使用异常的代码中所有函数的返回码可能比对使用异常的代码不执行任何操作要慢。
当然,您需要根据您的特定要求测量性能才能确定。
It's completely implementation dependent but many recent implementations have very little or no performance overhead when exceptions aren't thrown. In fact you are right. Correctly checking return codes from all functions in code that doesn't use exceptions can be slower then doing nothing for code using exceptions.
Of course, you would need to measure the performance for your particular requirements to be sure.
有一些例外的开销(正如其他答案所指出的)。
但如今你没有太多选择。尝试在项目中禁用异常,并确保所有依赖的代码和库都可以在没有异常的情况下编译和运行。
它们是否可以在禁用异常的情况下工作?
让我们假设他们这样做!然后对一些情况进行基准测试,但请注意,您必须设置“禁用异常”编译开关。如果没有这个开关,即使代码从不抛出异常,您仍然会产生开销。
There is some overhead with exceptions (as the other answers pointed out).
But you do not have much of a choice nowadays. Try do disable exceptions in your project, and make sure that ALL dependent code and libraries can compile and run without.
Do they work with exceptions disabled?
Lets assume they do! Then benchmark some cases, but note that you have to set a "disable exceptions" compile switch. Without that switch you still have the overhead - even if the code never throws exceptions.
唯一的开销是~6条指令,它们在函数开始处添加2个SEH并将它们留在函数末尾。无论线程中有多少次尝试/捕获,它总是相同的。
另外,局部变量是什么?我听到人们在使用 try/catch 时总是抱怨它们。我不明白,因为无论如何最终都会调用解构函数。另外,您不应让异常发生超过 1-3 次调用。
Only overhead is ~6 instructions which add 2 SEH at the start of the function and leave them at the end. No matter how many try/catches you have in a thread it is always the same.
Also what is this about local variables? I hear people always complaining about them when using try/catch. I don't get it, because the deconstructors would eventually be called anyways. Also you shouldn't be letting an exception go up more then 1-3 calls.
我拿了Chip Uni的测试代码并对其进行了一些扩展。我将代码分成两个源文件(一个有例外;一个没有)。我让每个基准测试运行 1000 次,并使用
clock_gettime()
和CLOCK_REALTIME
来记录每次迭代的开始和结束时间。然后我计算了数据的均值和方差。我在具有 16GB RAM 且运行带有内核 4.2.5-1-ARCH 的 ArchLinux 的 Intel Core i7 机器上使用 64 位版本的 g++ 5.2.0 和 clang++ 3.7.0 运行了此测试。您可以在此处找到扩展代码和完整结果。g++
No Exceptions
Exceptions
clang++
No Exceptions
Exceptions
C++ 仅例外使用 clang++ 会产生不小的性能损失,甚至这种损失也只有 ~14%。
I took Chip Uni's test code and expanded it a bit. I split the code into two source files (one with exceptions; one without). I made each benchmark run 1000 times, and I used
clock_gettime()
withCLOCK_REALTIME
to record the start and end times of each iteration. Then I computed the mean and variance of the data. I ran this test with 64-bit versions of g++ 5.2.0 and clang++ 3.7.0 on an Intel Core i7 box with 16GB RAM that runs ArchLinux with kernel 4.2.5-1-ARCH. You can find the expanded code and the full results here.g++
No Exceptions
Exceptions
clang++
No Exceptions
Exceptions
C++ Exceptions only incur a non-trivial performance penalty with clang++, and even that penalty is only ~14%.