这段代码会在每次迭代时获取元素吗?

时间:2013-05-17 11:32:25

标签: c++ performance loops call iteration

通常情况下,我会编写类似的代码。

auto elements = get_elements();
for(auto i : elements)
{
    // ...
}

我想知道我是否会使用下面的代码来改变性能。是get_elements()每次迭代还是只调用一次?

for(auto i : get_elements())
{
    // ...
}

此外,传统的for循环怎么样?如果我不修改我循环的元素,编译器是否会优化该代码以在每次迭代时不调用get_elements()

for(auto i = get_elements().begin(); i != get_elements().end(); ++i)
{
    // ...
}

1 个答案:

答案 0 :(得分:2)

  

我想知道我是否会使用下面的代码来改变性能

与往常一样,在性能方面,您应该通过测量来支持您的假设。

除了明确的测量结果表明您在该特定程序中存在瓶颈之外,没有任何其他证据应该是放弃更清晰,更简单的设计以支持更复杂,更不直观的设计的理由。根据定义,这将是过早优化

因此,选择最适合您意图的表单。这说,我可以回答以下问题:

  

get_elements()会在每次迭代时调用一次还是只调用一次?

,它只会被调用一次。此行为由C ++ 11标准的第6.5.4 / 1段规定:

  

对于基于范围的表格形式

for ( for-range-declaration : expression ) statement
     

range-init等同于括号

所包围的表达式
( expression )
     

[...]基于范围的for语句是等效的   到

{
    auto && __range = range-init; // <== HERE IS YOUR get_elements()!
    for ( auto __begin = begin-expr,
        __end = end-expr;    
        __begin != __end;
        ++__begin ) {
            for-range-declaration = *__begin;
            statement
        }
    }

关于你的第二个问题:

  

此外,传统的for循环如何?

这些对循环本身的目的不太清楚,而且更容易出错。我建议避免手动循环。

例如,仅通过查看其第一行,很明显基于范围的for循环的目的是遍历集合的所有元素。

对于手动展开的for循环,同样不明显,只是通过查看第一行,您不知道i变量是否会在循环内以任何方式递增或操纵。

this article by Herb Sutter中对此进行了详细讨论(参见问题2-a的解决方案)。