Does noexcept improve performance?
Top compilers produce code that is already optimized a lot like code that can't throw, and then the case when an exception occurs is handled by out-of-line code that the exception-handling mechanism finds by looking at meta-data concerning the function. I suppose there's some benefit in code size to omitting this when it's known not to be needed, though.
There are probably some cases where a nothrow specification does allow some specific optimization:
int main() {
int i = 0;
try {
++i;
thing_that_cannot_throw();
++i;
thing_that_can_throw();
++i;
} catch (...) {}
std::cout << i << "\n";
}
Here the second ++i could in theory be reordered before the call to thing_that_cannot_throw
(and i
just initialized to 2
). Whether it is in practice is another matter, though, since an implementation that makes guarantees about the state of variables in the debugger or in the stack above a function call, would want i
to have value 1
during that call even though it's a local variable not observable by any standard means.
I suspect that nothrow guarantees are more valuable to the programmer than to the compiler. If you're writing code that offers the strong exception guarantee then usually there will be certain critical operations you perform, that you need to offer the nothrow guarantee (swaps, moves and destructors being the common candidates).
Theoretically speaking, noexcept
would improve performance. But it might also cause some problems on the other hand.
In most of cases, it shouldn't be specified because the pros are too few to be considered and it might make your code upgrading painful. This post, written by Andrzej, introduces the reasons in detail.
If it's too long, just take these suggestions I conclude from it:
- Annotate functions with
noexcept
if- they were annotated with
throw()
already, - or they are good candidates(listed in post) and never throw for sure,
- or they are move-constructors, move-assignments whose
noexcept
annotation cannot be correctly deduced by compiler and their instances are supposed to be put into some STL container.
- they were annotated with
- Do not annotate the functions with
noexcept
if- you are really concerned about reduced performance,
- or about the risk of calling
std::terminate
, - or you are just not sure about the new feature,
- or you have doubts whether you should make your function
noexcept
or not.