Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Clear or resize QVector without releasing memory
QtWS25 Last Chance

Clear or resize QVector without releasing memory

Scheduled Pinned Locked Moved General and Desktop
9 Posts 6 Posters 6.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    SC-Jeffrey
    wrote on 21 May 2014, 21:44 last edited by
    #1

    How can I clear a QVector or resize it to have fewer items without causing the object to release the memory that it currently has reserved? I want to remove all items from the vector, but I also want the vector to keep its memory reserved because I anticipate immediately putting roughly just as many items back into it.

    The implementation of QVector::clear in 5.3.0 releases the memory, as documented. QVector::resize also releases the memory if the new size is less than half of the reserved size. The performance impact of these deallocations, followed by having to reallocate the memory as soon as new items are added back in, is significant. I would rather avoid this significant and counter-productive operation.

    I know about the QVector::squeeze function to release memory when I know it is the most opportune moment, but I have not noticed any functionality to prevent releasing memory.

    Should I be using a different container? I am currently using a QVector because I am making use of its contiguous block of data for more efficient low-level access and iteration.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      JKSH
      Moderators
      wrote on 22 May 2014, 00:18 last edited by
      #2

      Hi,

      There's no such functionality that I'm aware of.

      Do you call QVector::reserve() before adding your data? The performance hit you see could be from the vector having to reallocate memory multiple times as it grows.

      Also, are you storing large objects in your vector? You can consider storing (shared) pointers instead, so that clearing + adding doesn't involve lots of vector memory.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • C Offline
        C Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on 22 May 2014, 01:09 last edited by
        #3

        Another thing to consider - if you're going to immediately put some items back in, then maybe you can just overwrite existing ones without explicitly removing them.

        1 Reply Last reply
        0
        • A Offline
          A Offline
          Asperamanca
          wrote on 22 May 2014, 10:49 last edited by
          #4

          In a 2011 "qt-interest discussion":http://comments.gmane.org/gmane.comp.lib.qt.general/42277,using QVector::resize(0) was suggested as the best solution.
          However, some posters pointed out that while the docs hinted that resize would not deallocate memory, they didn't explicitly say so. The behavior might have changed since then. You might need to re-check the source code.

          Edit: If QVector::resize() was indeed changed, and no new way to resize a QVector without deallocating memory was introduced, I would actually consider this a semi-bug. Keeping memory reserved can be essential in embedded environments that are short of memory.

          1 Reply Last reply
          0
          • S Offline
            S Offline
            SC-Jeffrey
            wrote on 24 May 2014, 00:24 last edited by
            #5

            [quote author="JKSH" date="1400717911"]Do you call QVector::reserve() before adding your data? The performance hit you see could be from the vector having to reallocate memory multiple times as it grows.[/quote]
            I agree that reserving the prior capacity would be better than inserting without reserving, but it is still counterproductive to have to reallocate the same amount of memory right after it was deallocated.

            [quote author="JKSH" date="1400717911"]Also, are you storing large objects in your vector? You consider storing (shared) pointers instead, so that clearing + adding doesn't involve lots of vector memory.[/quote]
            In my particular case, my vector is already a container of pointers. But since this code can be called very frequently, any memory operation introduces a significant impact.

            [quote author="Chris Kawa" date="1400720984"]Another thing to consider - if you're going to immediately put some items back in, then maybe you can just overwrite existing ones without explicitly removing them.[/quote]
            If I knew I had exactly the same number of items every time, I could do this. Unfortunately I cannot guarantee that I will have exactly the same number of items every time. But I do know that in most cases where time efficiency is important, I expect to have very close to the same number of items, so I will likely require close to the same amount of memory. I don't want to have to deal with the extra complexity of handling conditions where I have more or fewer items than last time when the QVector object could very easily do what I want with a lot less effort.

            [quote author="Asperamanca" date="1400755759"]In a 2011 "qt-interest discussion":http://comments.gmane.org/gmane.comp.lib.qt.general/42277,using QVector::resize(0) was suggested as the best solution.
            However, some posters pointed out that while the docs hinted that resize would not deallocate memory, they didn't explicitly say so. The behavior might have changed since then. You might need to re-check the source code.

            Edit: If QVector::resize() was indeed changed, and no new way to resize a QVector without deallocating memory was introduced, I would actually consider this a semi-bug. Keeping memory reserved can be essential in embedded environments that are short of memory.[/quote]
            Thank you for the link. I agree that it would be acceptable to use QVector::resize(0) to clear all elements without releasing the memory. However, this is not the way it works now, at least in version 5.0.2~5.3.0. Right now, if more than half of the reserved elements are unused on a resize, the memory will be released (after copying the remaining data to a smaller memory block).

            It looks like I will have to report this as a bug, as there appear to be no efficient alternatives.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              Asperamanca
              wrote on 26 May 2014, 07:43 last edited by
              #6

              After a closer look at the code, it seems that a QVector would already shrink in 4.8

              Here's the relevant code for comparison:

              4.8.1:
              @
              template <typename T>
              void QVector<T>::resize(int asize)
              { realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ?
              QVectorData::grow(sizeOfTypedData(), asize, sizeof(T), QTypeInfo<T>::isStatic)
              : d->alloc); }@

              5.3:
              @
              template <typename T>
              void QVector<T>::resize(int asize)
              {
              int newAlloc;
              const int oldAlloc = int(d->alloc);
              QArrayData::AllocationOptions opt;

              if (asize > oldAlloc) { // there is not enough space
                  newAlloc = asize;
                  opt = QArrayData::Grow;
              } else if (!d->capacityReserved && asize < d->size && asize < (oldAlloc >> 1)) { // we want to shrink
                  newAlloc = asize;
                  opt = QArrayData::Grow;
              } else {
                  newAlloc = oldAlloc;
              }
              reallocData(asize, newAlloc, opt);
              

              }@

              If I didn't misread, the realloc option to shrink the vector is there in 4.8 just as it is in 5.3 - it's just hidden better.

              From which we learn: Don't trust postings, trust the code.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                SC-Jeffrey
                wrote on 26 May 2014, 18:24 last edited by
                #7

                Bug report submitted: https://bugreports.qt-project.org/browse/QTBUG-39293

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  Torgeir
                  wrote on 27 May 2014, 10:32 last edited by
                  #8

                  I have also needed this behavior and when looking at the code for QVector, it seems

                  @
                  vec.erase(vec.begin(), vec.end());
                  @

                  will do what you need. Unless I'm reading the code wrongly. Though, it is not documented to have this behavior and there are some comments in the code that suggests that it could also realloc/shrink, but currently doesn't.

                  The vector needs to not be shared at this point, but that would also be the case for clear() or resize(0) etc.

                  1 Reply Last reply
                  0
                  • E Offline
                    E Offline
                    exophoric
                    wrote on 3 Nov 2014, 22:01 last edited by
                    #9

                    Using a "QVarLengthArray":http://qt-project.org/doc/qt-5/qvarlengtharray.html#details solved this issue for my application.

                    Although, the documentation does not mention if issuing a clear() will deallocate the part of the array which is stored into the heap, you can be sure it can't delete the part you reserved on the stack. ;)

                    However, you are limited to a certain extent on the preallocated stack memory.

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved