++ iterator和iterator ++之间的性能差异?

Mat*_*att 26 c++ performance

我的同事声称对于对象类型,preincrement比post增量更有效

例如

std::vector<std::string> vec;

... insert a whole bunch of strings into vec ...

// iterate over and do stuff with vec.  Is this more efficient than the next 
// loop?
std::vector<std::string>::iterator it;
for (it = vec.begin(); it != vec.end(); ++it){

}

// iterate over and do stuff with vec.  Is this less efficient than the previous loop?
std::vector<std::string>::iterator it;
for (it = vec.begin(); it != vec.end(); it++){

}
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 51

Postincrement必须返回迭代器在递增之前的值; 所以,之前的值需要在使用适当的增量进行更改之前复制到某处,因此可以返回.额外的工作可能有点或很多,但它肯定不能小于零,与preincrement相比,它可以简单地执行递增,然后返回刚改变的值 - 无需复制//保存//等必要的.

所以,除非你特别必须有后增量(因为你在某种程度上使用了"增量前的值"),你应该总是使用preincrement代替.

  • 德罗伯特:是的,如果可以的话.并非所有迭代器类型都足够简单,可以进行这种优化.如果对象很大"足够",您可以放慢速度.它可以说几乎从不重要,但是人们在紧密的循环中使用这个成语,它确实可以. (2认同)

Mar*_*ork 17

默认的增量运算符如下所示:

class X
{
    X operator++(int)  // Post increment
    {
        X  tmp(*this);
        this->operator++(); // Call pre-increment on this.
        return tmp;
    }
    X& operator++()  // Pre increment
    {
        // Do operation for increment.
        return *this;
    }
};
Run Code Online (Sandbox Code Playgroud)

请注意,后增量是根据预增量定义的.所以后增量做同样的工作加上一些额外的工作.通常这是构造一个副本,然后通过副本返回副本(注意,预增量可以通过引用返回自身,但后增量不能).


The*_*lor 5

对于原始类型,我曾经这样做过.在1998/1999年,它曾经让我在Visual Studio上的许多程序中获得了大约10%的提升.不久之后,他们修复了优化器.后增量运算符在堆栈上创建了一个变量,复制了值,递增了源,然后从堆栈中删除了变量.一旦优化器检测到它没有被使用,好处就消失了.

大多数人并没有停止编码.:)我花了几年时间.

对于对象,我不确定它是如何工作的.我假设真正实现后增量需要一个复制操作符.它必须复制并使用副本进行操作,并增加源.

雅各