OSE
OSE

Reputation: 1026

Vector of vectors, reserve

Suppose I want to represent a two-dimensional matrix of int as a vector of vectors:

std::vector<std::vector<int> > myVec;

The inner dimension is constant, say 5, and the outer dimension is less than or equal to N. To minimize reallocations I would like to reserve space:

myVec.reserve(N);

What size is assumed for the inner vector? Is this purely implementation dependent? How does this effect the spatial locality of the data? Since the inner dimension is a constant is there a way to tell the compiler to use this constant size? How do these answers change if the inner vector's size changes?

Upvotes: 35

Views: 31073

Answers (3)

Ben Voigt
Ben Voigt

Reputation: 283961

Since your inner dimension is constant, I think you want

std::vector< std::array<int, 5> > vecs;
vecs.reserve(N);

This will give you preallocated contiguous storage, which is optimal for performance.

Upvotes: 23

The Quantum Physicist
The Quantum Physicist

Reputation: 26356

The inner vectors are initialized with the default constructor. So if you write:

vector<vector<int> > vecs;
vecs.reserve(10);

This is equivalent to calling the constuctor of vector<int> or vector<int>() for each element. Which means you'll have a zero-sized vectors. But remember, you can't use them unless you resize (not reserve) your vectors.

Remember, too, that it could be sometimes more efficient to resize with the initial size that you would need. So it's useful to do something like

vector<vector<int> > vecs(3,vector<int>(5));

This will create a vector with size 3, and each element will contain a vector of size 5.

Remember also, that it could be more efficient to use deque rather than vector if you're going to resize your vectors often. They're easy to use (as vectors) and you don't need to reserve, since the elements are not contiguous in memory.

Upvotes: 16

us2012
us2012

Reputation: 16263

The size of the inner vectors is completely irrelevant for resizing the outer vector. There are no locality guarantees for your bundle of vectors, the locality guarantee (i.e. contiguous block in memory) exists for a single vector only.

Remember that a vector object itself has constant sizeof-size, its actual data is usually dynamically allocated. The outer vector, to first approximation, is a contiguous block of N 'pointers' to the inner vectors. Your reserve call does not reserve memory for possible elements of inner vectors, but only for the inner vector objects themselves (i.e. their bookkeeping data and their pointers to their dynamically allocated data block).

Upvotes: 15

Related Questions