增加迭代器:++它比++更有效吗?

时间:2009-07-02 22:42:07

标签: c++ stl iterator

  

可能重复:
  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++ )

这是真的吗?如果是,效率提升背后的原因是什么?它所做的全部++ / ++是将迭代器移动到向量中的下一个项目,不是吗?

7 个答案:

答案 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++执行以下操作:

  1. 创建it
  2. 的副本
  3. 增量it
  4. 返回原始(非递增)it
  5. ++it执行以下操作:

    1. 增量it
    2. return it
    3. 因为it++创建了副本,所以可以说它“慢”。但是,任何体面的编译器都会针对大多数定义的类型优化这种差异。对于某些用户定义的类型,可以更快。

答案 3 :(得分:3)

有时是的。有些它会被优化掉并且是相同的。对于std :: vector&lt;&gt; (和其他标准迭代器)它很可能被优化为相同。

答案 4 :(得分:2)

是的,它更有效率,因为它需要返回对象的副本然后自行递增。

答案 5 :(得分:2)

有可能++会创建一个临时副本。

此外,在C ++中,有人可能会使postincrement运算符超载。

这两件事都可能会降低性能与预先增量。在实践中两者都不重要。特别是临时副本将被大多数编译器优化掉,因为For循环的第3个表达式中没有副作用。

答案 6 :(得分:0)

是。据我所知,++它比++更有效,因为它创建了一个临时对象,而++却没有。