QVector::remove(int i, int count) 从第一个删除时的性能

Posted

技术标签:

【中文标题】QVector::remove(int i, int count) 从第一个删除时的性能【英文标题】:QVector::remove(int i, int count) performance when removing from the first 【发布时间】:2014-03-19 07:46:14 【问题描述】:

我想像队列一样使用 QVector。那是因为我想访问指向向量中数据的原始指针,而 QVector 将数据连续放置。所以我在我的 QVector 中的一个线程中附加数据,并在另一个线程中从第一个读取计数元素并删除它们。

当您从 QVector 的中间移除时,数据会重新排列,并且会发生许多副本。我想知道从 QVector 的请求中删除计数元素时是否复制了数据,或者它的开销很小?有没有更好的方法来做到这一点?

【问题讨论】:

QVector 不是为排队元素设计的,您应该将数据包装在 QQueue 但是我无法通过指针访问QQueue中的数据。 指针指向什么? 正如我在您的另一个问题中所说的那样 - 您应该阅读一些有关数据结构及其复杂性的内容。如果你需要通过索引快速访问 - 你应该使用 QVector,如果你需要快速插入/删除你应该使用 QLinkedList。但在大多数情况下,使用 QList 就足够了。你原来的问题是什么?您在哪里遇到性能问题?你如何分析它们? (1) 为什么需要一个指向容器中原始数据的指针?您可以只堆分配您的数据,并将它们的指针存储在容器中。 (2) 几乎所有性能问题的答案都是“Profile it” 【参考方案1】:

你可以使用这个类来检查QVector::remove的性能:

#include <QDebug>

class Dummy

public:
    Dummy()
    
        qDebug() << "dummy ctor" << ++c1;
    

    Dummy(const Dummy &d)
    
        qDebug() << "dummy copy ctor" << ++c2;
    

    Dummy &operator=(const Dummy &d)
    
        qDebug() << "dummy asign" << ++c3;
    

    static int c1, c2, c3;
;

int Dummy::c1 = 0;
int Dummy::c2 = 0;
int Dummy::c3 = 0;

测试本身:

int main(int argc, char *argv[])

    QVector<Dummy> v;

    for (int i = 0; i < 100; ++i)
    
        v.append(Dummy());
    

    qDebug() << "adding finished";

    v.remove(0);
    v.remove(v.size() - 1);

    qDebug() << "end";

        return 0;

在此示例中,Dummyassign 运算符在您删除第一个元素时被调用 99 次,而在您删除最后一个元素时则根本不调用。

无论如何,如果您需要访问容器原始数据,我想您会遇到一些设计问题。 正如 JKSH 在 cmets 中所说,您可以为数据元素动态分配内存,然后将这些指针放入容器中。

【讨论】:

【参考方案2】:

问题是您正在寻找一种数据结构,其中数据是连续存储的,同时您需要重新排列数据(即从前面删除元素)。除非您要删除向量中的所有元素,否则此操作将始终需要移动数据以保持向量连续。

我可以建议优化设计性能的一种方法(除了使用列表而不是向量并放弃按指针访问)是编写一个自定义向量,其中删除第一个元素只会增加 front指针并且不重新排列数据。这将与删除第一个元素具有相同的效果,但不会降低性能。您还必须实现一个清理例程,该例程将在达到某个已删除元素的阈值时压缩向量,但您可以控制何时执行此清理,而不是在每次从队列中删除时执行。

【讨论】:

以上是关于QVector::remove(int i, int count) 从第一个删除时的性能的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode题解之Find All Numbers Disappeared in an Array

bzoj2662

Java冒泡排序

Leetcode-5222 Split a String in Balanced Strings(分割平衡字符串)

C#代码显示错误无法将类型“string”转换为“int”

HDU-Largest Rectangle in a Histogram-1506 单调栈