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

29 c++ iterator stl

可能重复:
在C++中i ++和++ i之间是否存在性能差异?

我正在编写一个程序,其中迭代器用于循环std :: vector.有人告诉我,在for语句中执行++会导致更高效的代码.换句话说,他们说:

for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); ++it )
Run Code Online (Sandbox Code Playgroud)

比跑得快

for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); it++ )
Run Code Online (Sandbox Code Playgroud)

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

aem*_*aem 35

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
}
Run Code Online (Sandbox Code Playgroud)

正如其他人所指出的那样,在某些情况下,某些编译器可能会对此进行优化,但如果您不使用返回值,则最好不要依赖此优化.此外,对于具有普通复制构造函数的类型,性能差异可能非常小,但我认为使用preincrement是C++中的一个好习惯.

  • 请注意,如果从未使用过,那么正常的编译器将优化掉旧值的副本. (3认同)
  • 确切地说:你不能保证preincrement比postincrement更有效,因为(a)标准不要求它,(b)很容易发明源代码和编译器的组合,其中两者同样有效. (2认同)
  • 同意:我认为尽可能使用preincrement,因为我无法想到它比post更糟糕的正当理由.如果某个类重载两个运算符(严重)并且以某种方式使preincrement更糟,那么调用者不能因为未能解决它而受到指责.我不认为人们应该承诺它"更有效"(许多人将其视为"严格更高效"),当没有这样的保证时,实际上通常它们在优化代码中是相同的. (2认同)

Ste*_*sop 9

它不太可能对矢量产生任何影响.

一般来说,++it极不可能慢于it++(假设一个合理的实现,如果它们超载),并且可能更快.原因是如果迭代器类本身都很复杂,那么因为it++必须在it递增之前返回值,所以实现通常会复制.

向量迭代器可能只是"指针"(在优化的非调试版本中),并且两个operator++s都将被内联.由于返回值未使用,因此通常会省略副本.所以它不会有任何区别.我有打字的习惯,++it因为:

1)有些日子它可能会有所不同,对于某些迭代器类型,我不想为这种类型做一些特别的事情.

2)我个人认为前缀运算符更清楚地表达了意图:"增加它",而不是"使用它然后增加".


the*_*der 5

it++ 执行以下操作:

  1. 创建一份 it
  2. 增量 it
  3. 返回原始(不递增) it

++it 执行以下操作:

  1. 增量 it
  2. 返回 it

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


Tho*_*mas 4

有时候是。对于某些,它会被优化并保持不变。对于 std::vector<> (和其他 std-iterators),它很可能会被优化为相同。


归档时间:

查看次数:

28036 次

最近记录:

7 年,3 月 前