Я хочу использовать QVector как очередь. Это потому, что я хочу получить доступ к необработанному указателю на данные в векторе, а QVector помещает данные непрерывно. Поэтому я добавляю данные в мой QVector в поток, а в другой поток читаю количество элементов из первого и удаляю их.
Когда вы удаляете из середины QVector, данные переставляются и происходит много копий. Я хочу знать, копируются ли данные при удалении элементов count из начала 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
Оператор assign вызывается 99 раз, когда вы удаляете первый элемент, и вообще не вызывается, когда вы удаляете последний элемент.
В любом случае, я полагаю, у вас есть некоторые проблемы с дизайном, если вам нужен доступ к необработанным данным контейнера.
Как JKSH сказал в комментариях, вы можете динамически распределять память для ваших элементов данных и затем помещать эти указатели в контейнер.
Проблема заключается в том, что вы ищете структуру данных, в которой данные хранятся непрерывно, и в то же время вам необходимо переставить данные (то есть удалить элемент спереди). Если вы не удаляете все элементы в векторе, эта операция всегда будет требовать перемещения данных, чтобы вектор оставался непрерывным.
Один из подходов, которые я могу предложить для оптимизации производительности вашего проекта (кроме использования списков вместо векторов и отказа от доступа по указателю), состоит в том, чтобы написать собственный вектор, в котором удаление первого элемента просто увеличивает front
указатель и не переставляет данные. Это будет иметь тот же эффект, что и удаление первого элемента, но без снижения производительности. Вам также потребуется реализовать процедуру очистки, которая сжимает вектор после достижения определенного порога удаленных элементов, но вы можете контролировать выполнение этой очистки, а не выполнять ее при каждом удалении из очереди.