将矢量大小()置于循环条件之外进行优化

时间:2011-06-18 11:04:10

标签: c++

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()并在循环条件中使用它?

5 个答案:

答案 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()存储在寄存器中,因此无法消除内存访问。