【问题标题】:Is C++11 is faster than C++03 in terms of efficiency? [closed]就效率而言,C++11 是否比 C++03 快? [关闭]
【发布时间】:2018-04-29 16:48:25
【问题描述】:

我在贸易公司工作,在这里延迟很重要。分配给我的项目是使用 c 和 c++98 部分的混合开发的,但我相信我们可以使用 C++11 制作相同的项目而不会降低效率。正如我的前辈所讨论的,他们说你应该坚持使用 C 和 c++03,因为它们在微观层面上比 C++11 更有效。 任何人都可以强调我如果我使用 C++11,我会得到更好的结果吗?

【问题讨论】:

  • 取决于你在做什么。对于真正性能关键的东西,我使用 C,但我确定那是因为我是一个老笨蛋。
  • C++98/03/11 是语言标准 - 效率(主要)取决于您编写的实际代码(也许您使用的编译器在优化方面有多好)。说 C++03 比 C++11 更高效没有任何意义
  • 任何 C++03 仍然是有效的 C++11。委员会竭尽全力确保“旧”代码仍然与升级时一样好。话虽如此,除非你有效地使用 C++11,否则你的结果不会很出色。
  • 测量程序。检查装配清单。向他们展示证据。

标签: c++ c++11 c++03 low-latency


【解决方案1】:

C++11 更快,因为引入了对象的移动。主要是在 STL 中使用此功能可以大大加快某些应用程序的速度,而无需对用户代码进行任何代码更改。可以比以前更高效地对应用程序进行编程。 constexpr 构造还可以使应用程序启动更快,因为对象可以驻留在小型控制器的闪存空间中,而不是将它们复制到 ram 中。还有更多功能有助于提高代码效率。例如,emplace_back 用于容器有助于就地生成对象,而不是创建和复制它们。

C++17 引入了保证复制省略,这在很多用例中也可以加快速度。

【讨论】:

  • 谁对的答案投了反对票?是的,新的复制语义,一种语言特性,可以让现有代码运行得更快。
【解决方案2】:

这大多是错误的。

首先,如果您将符合 C++03 的源代码提供给像 GCC 这样的编译器,那么如果您指定 --std=c++03--std=c++11 相比,生成的机器代码不太可能有任何不同。

其次,使用 auto 和“基于范围”之类的功能对于效率来说是中性的。 (在少数情况下,基于范围的 for 将允许编译器比简单循环更有效地优化终止条件的评估,但这种情况很少见。)

第三,有一些特性(如移动语义)对提高效率非常有益。

最后,在某些情况下,天真地编写 C++11 的效率会低于等效的 C++03 代码。例如:

std::vector<std::vector<big_struct>> big_2d_array;
for (auto v : big_2d_array)
    do_stuff(v);

这将复制 v 并且会很昂贵。它必须是:

for (auto &v : big_2d_array)
    do_stuff(v);

注意参考。 (我也推荐const,但这是一个单独的问题)。

【讨论】:

  • 是的,移动语义是对高性能代码真正有益的一项功能。我们在图像处理后端大量使用了它,它很有帮助。
  • auto 可能当表达式的类型不是程序员认为的那样时会有所帮助,并且转换需要一些成本
  • @Caleth:或者它可能是有害的。如果一个函数返回一个自动转换为FooFooBuilder,那么将函数的结果捕获为auto而不是Foo意味着转换将发生多次。
  • 但可能 FooBuilder 只是以某种可怕的骇人听闻的方式提供移动语义? :-)
  • @GemTaylor 通常 FooBuilder 是为了提供一个流畅的接口来为构造函数提供一些但不是全部的 57 个参数。所有繁重的工作都在“转换为 Foo”函数中完成。
【解决方案3】:

老实说,这高度依赖于特定的代码 sn-p。 C++11 只是 C++ 语言标准 (ISO/IEC 14882:2011) 的更新版本。

较新的版本仅更改某些表达式和语句的语法,以及某些关键字的使用,以及引入新的(和有用的)内容,例如rvalue reference (T&amp;&amp;)、auto type deduction (autodecltype)、variadic template parameters (template &lt;typename... Args&gt;) 等等。尽管某些介绍可能会帮助您编写更高效的代码(例如move semantics),但它本质上不会改变编译器从 C++ 源代码生成 CPU 指令的方式。。 p>

因此,在微指令级别,来自同一来源的编译指令在 C++98/0x/11 下大部分保持不变,因此在性能上应该不会有任何可观察到的差异。

实际上更重要的是您选择的算法和您编写的具体实现,以及编译器优化(通常是-O# 命令行参数)。使用新标准,您可以使用移动语义编写更快的代码,range-based for loopdecltype(auto)(不过这是 C++14)


事实上,当语言标准是提供给编译器的唯一不同选项时,此代码生成完全相同的汇编代码:

#include <iostream>
using std::cout;
using std::endl;

int main() {
    cout << "Hello world" << endl;
    return 0;
}

但是,当您开始使用 STL(它总是尽可能使用最新功能)时,它就会开始发挥作用:

#include <iostream>
#include <string>
using std::string;

string getString(void) {
    string str("");
    for (int i = 0; i < 100000; i ++)
        str.append("A");
    return str;
}

int main() {
    std::cout << getString() << std::endl;
    return 0;
}

【讨论】:

  • 当人们谈论留在 C++ 03 中时,通常意味着继续使用那个旧的编译器。无法通过检查循环本身来自动并行化或发出 SIMD 命令的一种。从这个意义上说,C++14/17 更快。不要忘记 STL、Boost 等。在过去的 14 年中有很多改进
  • 此外,新的复制语义意味着相同代码的巨大性能提升。
  • 为什么投反对票?还是我们有一个连续的downvoter?好在有一个 downvote 机器人可以删除连续的 downvotes。不知道它是否也标记了反对者。
  • c++11 生成更快的代码,特别是因为 STL 使用了很多优化的 c++ 特性。只需编译一个应用程序并检查它。使用大量 stl 容器的应用程序会加速很多。所以说“废话”是错误的!
  • @PanagiotisKanavos:在C++11 is as simple as a newer ... 的上下文中,这听起来对我来说完全是错误的。 c++11 中有太多的新特性可以提高效率,以至于这个答案指向了错误的方向。
【解决方案4】:

C++ - 语言 - 不会为各种操作(主要是容器)和“你不用为你不使用的东西付费”的一般概念提供超出复杂性限制 O(*) 的任何性能保证。

对此没有重大变化(除了可能更适合某些地方的新容器类型)。

[edit] 我忘记了:移动语义可以显着加快现有代码库的速度,而无需进行任何更改。 (但是,如果你一直在挤压周期,你可能不会受益。)

但是(C++ 中总是有一个)编译器通常会有所改进。显着性能提升的显着来源是链接时代码生成和自动矢量化等新技术,这些技术已经变得更加广泛和完善,并更好地支持当代 CPU 架构。

反对编译器升级只谈研究和测试的风险和成本。

直觉:您的上级会回避风险和变化。

“在微观层面上,C 和 c++03 [...] 比 C++11 [更] 高效” 很牛。除非你的前辈没有费心去学习 20 年前推出的新奇东西。

【讨论】:

  • 事实上,C++11 比它的前辈提供了一些更强大的 O(*) 保证:例如 std::list::size() 现在是立即的而不是线性的。
  • @GemTaylor: ...这实际上是一种折衷,因为这使得将列表分成两个 O(N) 而不是 O(1) - 这是将其留给实施。但是,是的,因为这会影响算法选择,“实现定义”在这里是一个不好的选择,而且由于拆分不是显式的列表操作,这似乎是正确的选择。
  • 虽然新的拼接实际上是你从分割中寻找的。​​span>
猜你喜欢
  • 2010-10-11
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多