Вектор векторов, резерв

Предположим, что я хочу представить двумерную матрицу int как вектор векторов:

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

Внутренний размер постоянный, например 5, а внешний размер меньше или равен N. Чтобы свести к минимуму перераспределение, я хотел бы зарезервировать место:

myVec.reserve(N);

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

Ответ 1

Поскольку ваше внутреннее измерение постоянное, я думаю, что вы хотите

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

Это даст вам предварительно распределенное непрерывное хранилище, которое является оптимальным для производительности.

Ответ 2

Размер внутренних векторов совершенно не имеет значения для изменения внешнего вектора. Для вашего пучка векторов нет никаких гарантий местности, гарантированность локальности (т.е. Непрерывный блок в памяти) существует только для одного вектора.

Помните, что сам векторный объект имеет константу sizeof -size, ее фактические данные обычно динамически распределяются. Внешний вектор, в первом приближении, является смежным блоком N 'указателей' на внутренние векторы. Ваш вызов reserve не резервирует память для возможных элементов внутренних векторов, но только для самих внутренних векторных объектов (т.е. Их учетных данных и их указателей на их динамически распределенный блок данных).

Ответ 3

Внутренние векторы инициализируются конструктором по умолчанию. Поэтому, если вы пишете:

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

Это эквивалентно вызову constuctor из vector<int> или vector<int>() для каждого элемента. Это означает, что у вас будут векторы нулевого размера. Но помните, вы не можете использовать их, если вы не измените размер (не резервируете) свои векторы.

Помните также, что иногда бывает более эффективным изменять размер с исходным размером, который вам понадобится. Поэтому полезно сделать что-то вроде

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

Это создаст вектор с размером 3, и каждый элемент будет содержать вектор размером 5.

Помните также, что было бы более эффективно использовать deque, а не вектор, если вы собираетесь часто изменять размер ваших векторов. Они просты в использовании (как векторы), и вам не нужно резервировать, поскольку элементы не смежны в памяти.