Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::vector resize(0) or clear() - but keep it's capacity

Tags:

c++

c++11

vector

I'm merging many objects into a single vector containing render data (a mesh). This vector gets cleared and refilled on each frame (well, almost).

The issue is that clearing and then again reserving the vector size has a huge impact on performance in my case, because clear() may also change the capacity.

In other words, I need to control when the capacity of the vector gets changed. I want to keep the old capacity for quite some time, until I decide myself that it's time to change it.

I see two options:

  • Figure out how to control when the capacity of std::vector is about to change
  • Implement a memory pool for large memory objects which will fetch a large data object of <= required size and reuse / release it as I need.

Update

In addition, what if for example a resize(10), and later a resize(5) was called (just for illustration, multiply actual numbers by some millions)?

Will the later call to resize(5) cause the vector to, maybe, reallocate?

like image 735
benjist Avatar asked Mar 16 '17 17:03

benjist


People also ask

Does std::vector resize change capacity?

The C++ function std::vector::resize() changes the size of vector. If n is smaller than current size then extra elements are destroyed. If n is greater than current container size then new elements are inserted at the end of vector.

Does vector clear reduce capacity?

Starting with C++11, we can call the vector::shrink_to_fit function after clear() , which reduces the vector's capacity to fir the size. It works by “requesting” a reallocation on the vector.

Does resizing a vector delete data?

Resizing a vector doesn't destroy the values stored in the vector (except for those beyond the new size when shrinking, of course), however growing a vector beyond its capacity will copy (or, in C++11, move) them to a new place, thus invalidating and iterators, pointers or references to those elements.

How do I reset my vector capacity?

To clear a vector and consume as little capacity as possible, use the swap trick: std::vector<T>(). swap(foo); This creates an empty vector, swaps its internals with foo , and then destroys the temporary vector, getting rid of the elements that once belonged to foo and leaving foo as if it was freshly created.


2 Answers

Actually the clear member function keeps the vector capacity unchanged. It only destroys (calls the destructor) each of the vector elements and sets the vector size to 0.

In this situation, at each iteration, I would call clear() to destroy all the vector elements, then call the member function reserve(size) which, in the case where the vector capacity is too small, will increase it to at least size.

like image 133
Oliv Avatar answered Sep 30 '22 17:09

Oliv


This vector gets cleared and refilled on each frame (well, almost).

I would recommend a different approach.

Create a class that acts as a buffer for the rendering data.

If I am not mistaken, you never reduce the capacity of the buffer. You only increase its capacity when needed.

Make sure that class is an implementation detail and only instance is ever constructed.

Here's a skeletal implementation of what I am thinking.

namespace Impl_Detail
{
   struct Buffer
   {
      size_t capacity;
      size_t size;
      std::vector<char> data;

      // Pick whatever default capacity makes sense for your need.
      Buffer(size_t cap = 100) : capacity_(cap), size_(0), data(cap) {}

      void ensureCapacity(size_t cap)
      {
         if ( capacity_ < cap )
         {
            capacity_ = cap;
            data.resize(capacity_);
         }
      }


      // Add any other helpful member functions as needed.
   };

   // Create an instance and use it in the implementation.
   Buffer theBuffer;
}
like image 42
R Sahu Avatar answered Sep 30 '22 19:09

R Sahu