我想像队列一样使用 QVector。那是因为我想访问指向向量中数据的原始指针,而 QVector 将数据连续放置。所以我在我的 QVector 中的一个线程中附加数据,并在另一个线程中从第一个读取计数元素并删除它们。
当您从 QVector 的中间移除时,数据会重新排列,并且会发生许多副本。我想知道从 QVector 的请求中删除计数元素时是否复制了数据,或者它的开销很小?有没有更好的方法来做到这一点?
您可以使用此类来检查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;
}
在此示例Dummy
中,当您删除第一个元素时,分配运算符被调用 99 次,而当您删除最后一个元素时,它根本不会被调用。
无论如何,如果您需要访问容器原始数据,我想您会遇到一些设计问题。正如 JKSH 在评论中所说,您可以为数据元素动态分配内存,然后将这些指针放入容器中。
问题是您正在寻找数据连续存储的数据结构,同时您需要重新排列数据(即从前面删除元素)。除非您要删除向量中的所有元素,否则此操作将始终需要移动数据以保持向量连续。
我可以建议优化设计性能的一种方法(除了使用列表而不是向量并放弃按指针访问)是编写一个自定义向量,其中删除第一个元素只会增加front
指针并且不会重新排列数据。这将与删除第一个元素具有相同的效果,但不会降低性能。您还必须实现一个清理例程,该例程将在达到某个已删除元素的阈值时压缩向量,但您可以控制何时执行此清理,而不是让它在每次从队列中删除时执行。