Производительность QVector :: remove (int i, int count) при удалении из первого

Я хочу использовать QVector как очередь. Это потому, что я хочу получить доступ к необработанному указателю на данные в векторе, а QVector помещает данные непрерывно. Поэтому я добавляю данные в мой QVector в поток, а в другой поток читаю количество элементов из первого и удаляю их.

Когда вы удаляете из середины QVector, данные переставляются и происходит много копий. Я хочу знать, копируются ли данные при удалении элементов count из начала QVector, или они имеют небольшие накладные расходы? Есть ли лучший способ сделать это?

0

Решение

Вы можете использовать этот класс для проверки 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 сказал в комментариях, вы можете динамически распределять память для ваших элементов данных и затем помещать эти указатели в контейнер.

3

Другие решения

Проблема заключается в том, что вы ищете структуру данных, в которой данные хранятся непрерывно, и в то же время вам необходимо переставить данные (то есть удалить элемент спереди). Если вы не удаляете все элементы в векторе, эта операция всегда будет требовать перемещения данных, чтобы вектор оставался непрерывным.

Один из подходов, которые я могу предложить для оптимизации производительности вашего проекта (кроме использования списков вместо векторов и отказа от доступа по указателю), состоит в том, чтобы написать собственный вектор, в котором удаление первого элемента просто увеличивает front указатель и не переставляет данные. Это будет иметь тот же эффект, что и удаление первого элемента, но без снижения производительности. Вам также потребуется реализовать процедуру очистки, которая сжимает вектор после достижения определенного порога удаленных элементов, но вы можете контролировать выполнение этой очистки, а не выполнять ее при каждом удалении из очереди.

1

По вопросам рекламы [email protected]