Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What algorithms and containers in the C++ 11 STL can go faster if a type is noexcept?

A debate came up at work regarding how much to care about using noexcept. We all know that noexcept doesn't really do a huge amount for the compiler's optimiser except for externally defined code which the compiler otherwise has to assume can throw because it can't know its implementation, so the only real other performance benefit of marking things noexcept is for code which makes use of std::move_if_noexcept<> which it would be assumed would be mostly STL containers and their algorithms.

The assessment would therefore be this: do not use noexcept unless:

  1. extern functions and classes where the implementation of a callable isn't known to the compiler.

  2. Move constructors, move assignment operators and swap for any type which might be contained in a STL container.

  3. Otherwise don't worry about it.

Is this a fair assessment? Are there other places in the STL which generate much more optimal code if something is noexcept? If so, which STL implementation is this and what needs to be marked noexcept for it to work, and what performance benefit results (fewer memory allocations, lower complexity)?

Edit: Made CashCow's suggested change to wording.

like image 711
Niall Douglas Avatar asked Oct 21 '14 10:10

Niall Douglas


1 Answers

Is this a fair assessment?

No... it's unnecessarily fragile during code evolution/maintenance. Consider what happens if you follow your rules for this code...

// awesome_lib.h
void f() noexcept; // out-of-line implementation: { }

// awesome_app.cpp
void c1() noexcept; // out-of-line implementation: { f(); }

// cool_app.cpp
void c2() noexcept; // out-of-line implementation: { f(); }

...then say f() wants to report a new class of issue via exceptions, so it removes noexcept and conditionally throws... unless all the client code calling f() - c1, c2, ... is found and updated, the applications may std::terminate instead of letting the exception propagate to whatever catch clause might otherwise be available. Why would you want that? Yes you could use the noexcept operator to express the noexcept nature of c1 and c2 in terms of f and other called functions, but that's verbose and fragile. It's not like const where compiler errors help you keep things consistent.

It's better to make targeted use of noexcept where it's required by a specific profiling-lead optimisation opportunity.

like image 183
Tony Delroy Avatar answered Sep 26 '22 00:09

Tony Delroy