来自优化方面的基于范围的 for 循环 C++11
Range-based for loop C++11 from optimization side
例如,我想打印矢量图的内容。 "traditional for" cycle(1) 或 C++11 one(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;
}
一个简单的答案:使用分析器。
更好的答案:您为什么担心性能?使用#2,它更清晰,更不容易出现 errors/typos.
答案:流式传输到 cout 的开销可能远远超过任何循环开销。但请看简单的答案。
没有根本原因可以解释为什么基于范围的 for 循环比手动循环慢。基于范围的for循环定义为相同的代码是一个相对优化的循环。
在你的例子中,每个循环迭代逻辑上调用 size()
。如果在循环中的任何一点编译器无法证明 size()
不能在您的循环中更改,则编译器必须实际调用 size()
(这通常涉及减去两个指针)并检查它。在您的手动循环情况下,这可能会降低一些性能。
在 for(:)
循环中,它可能会花费正确性,因为如果被循环的向量的开始或结束迭代器(或当前迭代器)在循环期间无效,循环将继续循环旧的可能会导致迭代器和未定义的行为。
所以这两个循环(通常)不等价。
在循环范围不变的情况下,for(:)
循环的性能与大多数仅遍历元素的手工制作的循环一样好,甚至更好,因为大多数手工制作的循环不要制作 end()
的副本并与该副本进行比较。
在这种特殊情况下,IO 的开销(以及较小程度上的格式化)将大量压倒任何循环开销。
例如,我想打印矢量图的内容。 "traditional for" cycle(1) 或 C++11 one(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;
}
一个简单的答案:使用分析器。
更好的答案:您为什么担心性能?使用#2,它更清晰,更不容易出现 errors/typos.
答案:流式传输到 cout 的开销可能远远超过任何循环开销。但请看简单的答案。
没有根本原因可以解释为什么基于范围的 for 循环比手动循环慢。基于范围的for循环定义为相同的代码是一个相对优化的循环。
在你的例子中,每个循环迭代逻辑上调用 size()
。如果在循环中的任何一点编译器无法证明 size()
不能在您的循环中更改,则编译器必须实际调用 size()
(这通常涉及减去两个指针)并检查它。在您的手动循环情况下,这可能会降低一些性能。
在 for(:)
循环中,它可能会花费正确性,因为如果被循环的向量的开始或结束迭代器(或当前迭代器)在循环期间无效,循环将继续循环旧的可能会导致迭代器和未定义的行为。
所以这两个循环(通常)不等价。
在循环范围不变的情况下,for(:)
循环的性能与大多数仅遍历元素的手工制作的循环一样好,甚至更好,因为大多数手工制作的循环不要制作 end()
的副本并与该副本进行比较。
在这种特殊情况下,IO 的开销(以及较小程度上的格式化)将大量压倒任何循环开销。