如何解决迭代const容器时,编译器会展开“ for”循环吗?
在C ++ 11中,当迭代如下容器时,我们可以使用更简单的“ for”循环:
for (auto i : {1,2,3,4})
...;
但是,我不知道这种代码的效率。具体来说:
- {1、2、3、4}的类型是什么?它是原始数组,或转换为其他容器,例如std :: vector?
- 编译器会展开循环吗?
更新:假设我们正在使用-O2,并且循环中的代码仅是一些操作。 作为我的情况,我想向上,向下,向右放大四个方向,并使用direction参数调用一个函数。我只是在乎程序是否可以达到最佳性能。
非常感谢您!
解决方法
{1、2、3、4}的类型是什么?
std::initializer_list
将根据该初始化程序构造。正在迭代。您甚至需要包含<initializer_list>
才能使此工作正常。
编译器会展开循环吗?
该语言不能保证循环展开。您可以通过编译和检查生成的程序集来确定特定的编译器是否通过特定的目标CPU展开具有特定选项的特定循环。
也就是说,迭代次数在编译时是已知的,因此,可能是编译器展开整个循环的原因。
假设我们正在使用-O2
就其价值而言,-O2不会启用-funroll-loops。在添加该选项之前,请阅读其文档:
-funroll-loops
展开循环,可以在编译时或进入循环时确定其迭代次数。 -funroll-loops暗示 -frerun-cse-after循环。此选项使代码更大,并且可能会或可能不会使它运行得更快。
在此示例中,Clang确实展开了循环:https://godbolt.org/z/enKzMh,而GCC却未展开:https://godbolt.org/z/ocfor8
,没有保证,但是编译器可以优化某些情况,因此很可能最终获得好的代码。
例如,可以完全优化一个:
#include <initializer_list>
// Type your code here,or load an example.
int sum() {
int sum = 0;
for (auto i : {1,2,3,4}) {
sum += i;
}
return sum;
}
int main() {
return sum();
}
用-O3
编译,gcc可以推断出计算结果为10:
sum():
mov eax,10
ret
main:
mov eax,10
ret
在一个真实的示例中,编译器可能无法对其进行优化,因此您必须进行验证。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。