66

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?

user189169
  • 855
  • 1
  • 7
  • 7
  • Dupe of http://stackoverflow.com/questions/691168/how-much-footprint-does-c-exception-handling-add among others –  Dec 13 '09 at 22:09
  • 1
    @Neil: I think that that other question is more about footprint (i.e. memory/executable size overhead) where as this is about execution speed. – CB Bailey Dec 13 '09 at 22:13
  • My answer to it at least is very much about performance, as are some of the others. Possibly they shouldn't have been, but its a bit late now to change them :-) –  Dec 13 '09 at 22:20
  • @Neil: Oh yes, I only read the question, but some answers to that question are almost *more* relevant to this question than the question they are attached to. – CB Bailey Dec 13 '09 at 22:23
  • Possible duplicate of [Are Exceptions in C++ really slow](https://stackoverflow.com/questions/13835817/are-exceptions-in-c-really-slow) – underscore_d Oct 23 '17 at 11:19

6 Answers6

56

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.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
avakar
  • 32,009
  • 9
  • 68
  • 103
  • 1
    The statement about Visual Studio causing overhead while other compilers don't - is this still true today, 4 years later? – rich.e Jan 31 '14 at 02:58
  • 2
    @rich.e, yes, and it will not change. C++ exceptions are build over Windows structured exceptions (which is not going to change as all __try/__except constructs would stop catching C++ exceptions), and structured exceptions are part of the Windows x86 ABI. – avakar Jan 31 '14 at 14:02
  • 1
    @avakar Doesn't it depend on whether you use `Yes (/EHsc)` or `Yes with SEH exceptions (/EHa)` for the compiler options? – Aidiakapi Jun 22 '15 at 16:55
  • I thinks [this answer](https://stackoverflow.com/a/16785259/4123703) explained better nowadays. – Louis Go Sep 22 '21 at 08:14
16

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.

Frederik Slijkerman
  • 6,471
  • 28
  • 39
11

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.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • Presumably the main cost for checking return codes is the `if` branch. In exception-based code, don't you have to have the `if` statement some place else, in order to `throw` the correct exception anyway? Point is, if things can go wrong, you're down to `if` statements at some point. But, if a library below you throws exceptions (such `std::vector::at()`) and you are bounds checking as well, you're _doubling_ the error checking cost. – bobobobo Dec 10 '13 at 23:43
  • 1
    @bobobobo: but if you have a function A that calls 100 other functions, the version with error codes have to have an if branch between each function call, whereas the version with exceptions has no additional if branches at all. – Mooing Duck Dec 18 '13 at 22:28
  • 1
    It's true that `try { A() ; B() ; C() ; } catch { ( ExceptionType ) }` has no `if` in between the calls to `A()`, `B()`, `C()`, whereas in the exception free code you'd have `if( !A() ){handle;} if(!B()){ handle}`.. so I do see you have a bit of _double-if_ going on with not using exceptions. __But__, is the cost of the _double-if_ worse than the notorious `catch` resolution cost mentioned above (compiler dependent). – bobobobo Dec 19 '13 at 00:50
1

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.

Frunsi
  • 7,099
  • 5
  • 36
  • 42
0

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.

user230821
  • 1,093
  • 3
  • 12
  • 21
  • I think the point about local variables is that it takes some more tinkering/work to figure out what to destroy when an exception is in flight as opposed to the normal case. At least, that's what I've heard. (I suppose they might be trying to keep code size down, but I'm not sure) – Macke Dec 13 '09 at 23:17
-2

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() with CLOCK_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
  • Average: 30,022,994 nanoseconds
  • Standard Deviation: 1.25327e+06 nanoseconds
Exceptions
  • Average: 30,025,642 nanoseconds
  • Standard Deviation: 1.83422e+06 nanoseconds

clang++

No Exceptions
  • Average: 20,954,657 nanoseconds
  • Standard Deviation: 426,662 nanoseconds
Exceptions
  • Average: 23,916,638 nanoseconds
  • Standard Deviation: 1.72583e+06 nanoseconds

C++ Exceptions only incur a non-trivial performance penalty with clang++, and even that penalty is only ~14%.

Elzair
  • 452
  • 1
  • 4
  • 11
  • Down voted because the testsuite on github that you link to doesn't really test what the OP wants to know. It basically only measures if a function that contains a throw (that is never reached) is slower than code that doesn't. What you SHOULD measure if whether or not a try { } catch { } block is slower than none. – Carlo Wood Sep 25 '18 at 18:48