fibs是一个std :: vector。使用g ++,我被建议从循环中取出fibs.size(),以便每次都保存计算(因为向量可能会改变)
int sum = 0;
for(int i = 0; i < fibs.size(); ++i){
if(fibs[i] % 2 == 0){
sum += fibs[i];
}
}
当然,编译器中有一些数据流分析会告诉我们fibs不会改变大小。在那儿?或者我应该将其他变量设置为fibs.size()并在循环条件中使用它?
答案 0 :(得分:4)
编译器可能会确定它不会改变。即使它确实如此,向量的size()
也是O(1)操作。
答案 1 :(得分:4)
除非您知道这是一个问题,否则请保持原样。首先使其正确,然后清楚,然后快速(如有必要)。
无论如何, vector::size
非常快。在我看来,编译器可能会优化这种情况,因为很明显,矢量没有被修改,所有调用的函数都会被内联,所以编译器可以告诉你。
您可以随时查看生成的代码,看看是否发生了这种情况。
如果您确实想要更改它,您需要能够测量之前和之后所需的时间。这是相当多的工作 - 你可能有更好的事情要做。
答案 2 :(得分:3)
size()是常量时间操作,这样调用它没有任何代价。如果您关注性能和更一般的方法来完成集合,请使用迭代器:
int sum = 0;
for(auto it = fibs.cbegin(); it != fibs.cend(); ++it) {
if((*it) % 2 == 0){
sum += *it;
}
}
答案 3 :(得分:2)
我认为你错过了另一个更重要的观点:这个循环会导致你的应用程序变慢吗?如果您不确定(即如果您没有进行过分析),您可能会专注于应用程序的错误部分。
在编写程序(编码指南,应用程序的架构(更大图片),变量名称,函数名称,类名,可读性等)时,你必须要记住数以千计的事情,你可以忽略速度初始实施期间的代码(至少95%的时间)。这将使您能够专注于更重要且更有价值的事物(如正确性,可读性和可维护性)。
答案 4 :(得分:1)
在您的示例中,编译器可以轻松分析流并确定它不会更改。在更复杂的代码中,它不能:
for(int i = 0; i < fibs.size(); ++i){
complicated_function();
}
complicated_function
可以更改fibs
。但是,由于上面的代码涉及函数调用,编译器无法将fibs.size()
存储在寄存器中,因此无法消除内存访问。