【问题标题】:Range-based for loop C++11 from optimization side [duplicate]优化方面的基于范围的循环C ++ 11 [重复]
【发布时间】:2015-03-13 18:53:13
【问题描述】:

例如,我想打印矢量的内容。什么会执行得更快,“传统的 for”循环(1)还是 C++11 循环(2)?还是根本没有速度差异?任何信息表示赞赏。

1)

for (int i=0;i<FooBar_vector.size();i++)
    {
           cout<<FooBar_vector[i]<<endl;
    }

2)

for (auto &val : FooBar_vector) 
    {
           cout<< val <<endl;
    }

【问题讨论】:

  • 您可以对其进行基准测试并查看...但老实说,如果您使用优化进行编译,它们应该是相同的。如果有差异(这会让我感到惊讶),我认为这不会很明显,因为打印文本和刷新流将花费绝大多数时间,我预计。
  • 一个值得注意的快速事情是您可以将endl 更改为“\n”。然后在循环之后,调用cout.flush()
  • 我对这个问题做了-1,因为“哪个更快...... X 或 Y”是一个基本上不应该在 SO 上问的问题。你应该做的是自己分析代码。
  • 如果您的优化器不烂,请使用基于范围的。如果确实很糟糕,请使用指针算术。无论哪种方式,循环本身都不会是小偷,输出会。
  • 相比之下,@JohnDibling“为什么这段代码更快”是一个更好的问题(假设明确提到了优化标志/编译器/硬件、可重现的示例等)

标签: c++ performance c++11 for-loop cycle


【解决方案1】:

一个简单的答案:使用分析器。

更好的答案:您为什么担心性能?使用#2,它更清晰,更不容易出错/错别字。

答案:流式传输到 cout 的开销可能远远超过任何循环开销。但请看简单的答案。

【讨论】:

    【解决方案2】:

    基于范围的 for 循环比手动循环慢没有根本原因。基于范围的for循环被定义为相同的代码是一个相对最优的循环。

    在您的情况下,每个循环迭代逻辑上调用size()。如果在循环中的任何点编译器无法证明size() 不能在您的循环中更改,编译器必须实际调用size()(这通常涉及减去两个指针)并检查它。在您的手动循环情况下,这可能会降低一些性能。

    for(:) 循环中,它可能会花费正确性,因为如果被循环的向量在循环期间其开始或结束迭代器(或当前迭代器)无效,则循环将继续循环遍历旧迭代器和未定义的行为可以产生。

    所以这两个循环(通常)不是等效的。

    在循环范围不变的情况下,for(:) 循环的性能与大多数仅迭代元素的手工循环一样好,或者更好,因为大多数手工循环不会使end() 的副本并与该副本进行比较。

    在这种特殊情况下,IO 开销(在较小程度上还有格式化)将大大超过任何循环开销。

    【讨论】:

      猜你喜欢
      • 2021-04-08
      • 1970-01-01
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      • 2015-11-03
      相关资源
      最近更新 更多