简体   繁体   English

如果类型为noexcept,C ++ 11 STL中的哪些算法和容器可以更快?

[英]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. 关于使用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. 我们都知道noexcept对于编译器的优化器并没有真正做大量的事情,除了外部定义的代码,编译器否则必须假设它可以抛出,因为它无法知道它的实现,因此标记事物的唯一真正的其他性能优势noexcept用于使用std :: move_if_noexcept <>的代码,假定它主要是STL容器及其算法。

The assessment would therefore be this: do not use noexcept unless: 因此评估会是这样: 使用noexcept,除非:

  1. extern functions and classes where the implementation of a callable isn't known to the compiler. extern函数和类,其中编译器不知道可调用的实现。

  2. Move constructors, move assignment operators and swap for any type which might be contained in a STL container. 移动构造函数,移动赋值运算符并交换可能包含在STL容器中的任何类型。

  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? STL中还有其他地方可以产生更优化的代码吗? 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)? 如果是这样,哪个STL实现是这个,什么需要标记为no,除了它工作,以及什么性能的好处导致(更少的内存分配,更低的复杂性)?

Edit: Made CashCow's suggested change to wording. 编辑:使CashCow建议更改措辞。

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. ...然后说f()想要通过异常报告一个新的问题类,所以它删除noexcept和条件抛出...除非所有客户端代码调用f() - c1c2 ,...被找到并更新,应用程序可能std::terminate而不是让异常传播到可能的其他catch子句。 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. 是的你可以使用noexcept运算符来表达c1c2f和其他被调用函数方面的noexcept性质,但这是冗长而脆弱的。 It's not like const where compiler errors help you keep things consistent. 它不像const那样编译器错误可以帮助你保持一致。

It's better to make targeted use of noexcept where it's required by a specific profiling-lead optimisation opportunity. 最好有针对性地使用noexcept ,特定的分析 - 领导优化机会需要它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM