PDA

View Full Version : QVector copying data with remove()



Momergil
10th June 2014, 21:16
Hello!

I'm developing a graph in Qwt in which the new data appears in the right side while the old data is cut out in the left. Using a QVector<double> to storage the data, that would mean to use a QVector::append() together with a QVector::remove(0,1), right?

The problem is that I supposed that in doing remove(0,1), QVector copies all data after the first (now removed) item to a previous position (so now the data that was in position 1 is copied to position 0, position 2 is copied to position 1 and so on), what means a huge processing.

Is that true? And if it so, how may I get around this problem?

Thanks,

Momergil

d_stranz
10th June 2014, 21:52
If you aren't changing the size of the QVector (in other words, just removing one entry at the beginning and adding a new one at the end) you can do this:

Use the QVector::data() method to return a double * pointer to the start of the internal array. Use memcpy() to copy N - 1 items starting at the N = 1 position to the N = 0 position, then assign the Nth entry to your new value (using QVector::operator[]() if you want).

Since you aren't changing either the size of the array or where it lives in memory but are just changing the value of the entries, this should be safe (and fast).

Momergil
10th June 2014, 22:00
Use memcpy() to copy N - 1 items starting at the N = 1 position to the N = 0 position, then assign the Nth entry to your new value (using QVector::operator[]() if you want).

this should be safe (and fast).

Thanks d_stranz for the reply.

Well, how exactly the use of memcpy() makes it faster? :)

d_stranz
10th June 2014, 23:34
Well, how exactly the use of memcpy() makes it faster?

It may not make it faster. It depends on how QVector is implemented. QVector might use memcpy() internally to copy the contents of the vector when you remove() something from it. However, by manipulating the double * pointer directly, you can be sure that nothing else will happen to cause a reallocation of the memory. That would be the slow part.

There is no way to avoid copying the contents of the QVector when you remove something from the beginning or middle. The only way to avoid copying is to use some other data collection, like QList<>.

I haven't used Qwt for a long time, so I do not know if Qwt 6 supports the use of anything except QVector<> or other contiguous data collections. It might be possible to write an adapter class that uses QList<> internally, but looks like QVector<> to Qwt. I don't know. If there is a Qwt data interface that uses iterators, you could use any collection class that has forward iterator semantics.

Momergil
13th June 2014, 13:11
It might be possible to write an adapter class that uses QList<> internally, but looks like QVector<> to Qwt.

Now THAT would be awesome! :) Have any ideas on how could that be done?

wysota
13th June 2014, 13:16
The only way to avoid copying is to use some other data collection, like QList<>.
Not really. QList is implemented in a similar way as QVector with the only important difference that QVector always grows "at the far end" while QList can grow in both directions (meaning that if you need to insert an element in the first half of the data structure, the list will grow at the near end, if you insert in the second half, it will grow at the far end). You probably meant QLinkedList but that's very rarely used as random access to a linked list is not possible so it is very slow for such cases.

yeye_olive
13th June 2014, 16:19
If I understand your problem correctly, the data structure you need is a queue. Unless QVector is forced upon you by some interface, you should pick QQueue instead.

Momergil
13th June 2014, 18:50
Unless QVector is forced upon you by some interface

Yep! I'm using Qwt which uses a QVector<QPointF> internally to storage the plotting data :T So I can't avoid using QVector for the plotting, although it maybe faster to copy a entire new data to a QVector instead of using append + remove(0,1); but I wouldn't know that.