Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将vector size()从循环条件中取出以进行优化_C++ - Fatal编程技术网

C++ 将vector size()从循环条件中取出以进行优化

C++ 将vector size()从循环条件中取出以进行优化,c++,C++,fibs是一个std::向量。使用g++时,有人建议我将fibs.size()从循环中去掉,以节省每次计算的时间(因为向量可能会改变) int和=0; 对于(int i=0;i

fibs是一个std::向量。使用g++时,有人建议我将fibs.size()从循环中去掉,以节省每次计算的时间(因为向量可能会改变)

int和=0;
对于(int i=0;i

当然,编译器中有一些数据流分析会告诉我们fibs不会改变大小。有?或者我应该将其他变量设置为fibs.size()并在循环条件中使用它吗?

编译器可能会确定它不会更改。即使是这样,向量的
size()
也是一个O(1)操作。

除非您知道这是一个问题,否则请保持原样。首先要使它正确,然后使它清楚,然后使它快速(如果必要的话)

无论如何,
vector::size
速度非常快。在我看来,编译器可能会对这种情况进行优化,因为很明显,向量没有被修改,所有调用的函数都将内联,因此编译器可以判断

您可以随时查看生成的代码,看看是否发生了这种情况

如果你真的想改变它,你需要能够测量它前后所花费的时间。这是一个相当大的工作量-你可能有更好的事情要做。

size()是一个常数时间操作,这样叫没有任何惩罚。如果您关心性能和使用更通用的方法遍历集合,请使用迭代器:

int sum = 0;
for(auto it = fibs.cbegin(); it != fibs.cend(); ++it) {
    if((*it) % 2 == 0){
        sum += *it;
    }
}

在您的示例中,编译器可以轻松地分析流,并确定它不会改变。在更复杂的代码中,它不能:

for(int i = 0; i < fibs.size(); ++i){
    complicated_function();
}
for(int i=0;i

复杂的函数
可以更改
fibs
。但是,由于上面的代码涉及函数调用,编译器无法在寄存器中存储
fibs.size()
,因此无法消除内存访问。

我认为您缺少了另一个更重要的点:此循环是否会导致应用程序的速度减慢?如果您不确定(即,如果您尚未分析),则可能会将注意力集中在应用程序的错误部分


在编写程序时,您已经需要记住成千上万的事情(编码准则、应用程序的体系结构(大图)、变量名、函数名、类名、可读性等),您可以在初始实现过程中忽略代码的速度(至少95%的时间)。这将使您能够专注于更重要、更有价值的事情(如正确性、可读性和可维护性)。

1+1+2+3+5+…+Fn=Fn+2-1。因此,建议您的人不希望每次都计算
大小
(g++中的减法,在优化之前),但不介意调用
操作符[]
(与优化之前使用迭代器相比,还有额外的加法)两次。什么,甚至永远。最好是查看发出的指令,或者对其计时。Steve,如果我知道向量的大小保证不会改变,那么使用运算符[]是否可以节省时间?此外,我是一个C++小丑。那么,使用迭代器更快吗?@shuttle87:我是说,如果有人(给出此建议的人)打算对性能做出疯狂的概括,我有点惊讶,他们猜测
size()
比访问变量慢,但他们没有猜到
运算符[]
比使用迭代器或指针慢。我猜不出优化器会做什么——它实际上可能会设法用指针替换索引
I
,但要做到这一点,它必须以某种方式说服自己,向量永远不会重新分配,这几乎比说服自己它可以提升
大小
的值容易得多。基本问题是
操作符[]
必须从向量对象中加载向量的基指针(并添加索引),就像gcc上的
size()
从向量对象中加载基指针和结束指针(并减去它们)。因此,在这两种情况下,这几乎是一种精巧的微观优化。就个人而言,我不会担心这两个问题,直到这段代码被证明是瓶颈,然后检查发出的代码。但如果你要担心其中一个,我认为你应该同时担心这两个。O(1)只说它是有界的。这仍然可能是昂贵的(好吧,不是一个向量)。
for(int i = 0; i < fibs.size(); ++i){
    complicated_function();
}