可能重复:
Is there a performance difference between i++ and ++i in C++?
我正在编写一个程序,其中迭代器用于循环std :: vector。有人告诉我,在for语句中执行++会导致更高效的代码。换句话说,他们说:
for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); ++it )
跑得比
快for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); it++ )
这是真的吗?如果是,效率提升背后的原因是什么?它所做的全部++ / ++是将迭代器移动到向量中的下一个项目,不是吗?
答案 0 :(得分:33)
preincrement更快的原因是后增量必须复制旧值才能返回。正如GotW #2所说的那样,“Preincrement比postincrement更有效,因为对于postincrement,对象必须递增自身,然后返回一个包含其旧值的临时值。请注意,即使像int这样的内置函数也是如此。”
GotW #55提供了后增量的规范形式,表明它必须进行预增量再加上一些工作:
T T::operator++(int)
{
T old( *this ); // remember our original value
++*this; // always implement postincrement
// in terms of preincrement
return old; // return our original value
}
正如其他人所指出的那样,某些编译器可能会在某些情况下对此进行优化,但如果您不使用返回值,则最好不要依赖此优化。此外,对于具有普通拷贝构造函数的类型,性能差异可能非常小,但我认为在C ++中使用preincrement是一个好习惯。
答案 1 :(得分:8)
不太可能对矢量产生任何影响。
通常,++it
极不可能比it++
慢(假设一个合理的实现,如果它们超载),并且可能更快。原因是如果迭代器类本身很复杂,那么因为it++
必须在it
递增之前返回值,所以实现通常会复制。
向量迭代器可能只是“指针”(在优化的非调试版本中),并且两个operator++
都将被内联。由于返回值未使用,因此通常会省略副本。所以它不会有任何区别。我习惯输入++it
因为:
1)有些日子它可能会有所不同,对于某些迭代器类型,我不想为这种类型做一些特殊的事情。
2)我个人认为前缀运算符更清楚地表达了意图:“增加它”,而不是“使用它然后增加”。
答案 2 :(得分:5)
it++
执行以下操作:
it
it
it
++it
执行以下操作:
it
it
因为it++
创建了副本,所以可以说它“慢”。但是,任何体面的编译器都会针对大多数定义的类型优化这种差异。对于某些用户定义的类型,可以更快。
答案 3 :(得分:3)
有时是的。有些它会被优化掉并且是相同的。对于std :: vector&lt;&gt; (和其他标准迭代器)它很可能被优化为相同。
答案 4 :(得分:2)
是的,它更有效率,因为它需要返回对象的副本然后自行递增。
答案 5 :(得分:2)
有可能++会创建一个临时副本。
此外,在C ++中,有人可能会使postincrement运算符超载。
这两件事都可能会降低性能与预先增量。在实践中两者都不重要。特别是临时副本将被大多数编译器优化掉,因为For循环的第3个表达式中没有副作用。
答案 6 :(得分:0)
是。据我所知,++它比++更有效,因为它创建了一个临时对象,而++却没有。