++迭代器和迭代器c ++之间的性能差异?

时间:2009-08-20 04:07:25

标签: c++ performance

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

e.g。

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++){

}

7 个答案:

答案 0 :(得分:50)

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

所以,除非你特意必须有后增量(因为你在某种程度上使用了“增量前的值”),你应该总是使用preincrement。

答案 1 :(得分:16)

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

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;
    }
};

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

答案 2 :(得分:5)

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

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

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

雅各

答案 3 :(得分:4)

我已经读过它与具有不错的优化器的编译器没有区别。由于整体循环逻辑对于两者都是相同的,因此使用预增量作为良好的编程习惯是有意义的。这样,如果程序员遇到“次优”编译器,则可以确保最佳结果。

答案 4 :(得分:3)

说真的,除非你实际上因为调用后增量而不是预增量而遇到性能问题性能差异只会在非常罕见的情况下发生


<强>更新

例如,如果您的软件是气候模拟,operator++会导致模拟向前移动一步(++simulation为您提供模拟中的下一步,而simulation++复制模拟中的当前步骤,推进模拟,然后交给你副本)然后性能将是一个问题。

更现实地,在评论中,原始提问者提到我们正在讨论具有(显然)实时要求的嵌入式项目。在这种情况下,您需要实际查看您的具体实现。我严重怀疑你会有明显的减速迭代迭代std::vector后增量而不是预增量,尽管我没有对此问题的任何STL实现进行基准测试。


出于性能原因,不要选择其中一个。为清晰/维护原因选择一个在另一个上。我个人默认预先增加,因为我通常不会在递增之前给出该值是什么。

如果您看到++i而不是i++时大脑爆炸,可能是时候考虑进入不同的工作线。

答案 5 :(得分:1)

答案 6 :(得分:0)

我知道这就像航空中的“机库飞行”。我确信它纯粹是学术性的,你知道如果它产生了不同的差异,你需要重新思考你的代码。

示例:我对一些关于性能调优问题的答案给出了评论,它是这样的:

Person:我尝试了随机暂停和查看调用堆栈的方法。我做了几次,但没有任何意义。一直以来,它都是一些迭代器增量代码。这有什么用呢?

我:太好了!这意味着几乎所有的时间都在增加迭代器。只需向上看堆栈,看看它来自哪里。用简单的整数增量替换它,你将获得大量加速。

当然,你可能更喜欢迭代器增量的漂亮,但是很容易找出它是否会让你的性能下降。