Как установить начальный размер std :: vector?

131

У меня есть, vector<CustomClass*>и я помещаю много элементов в вектор, и мне нужен быстрый доступ, поэтому я не использую список. Как установить начальный размер вектора (например, 20 000 разрядов, чтобы не копировать при вставке нового)?

Дамир
источник
1
Для этого в любой std::vectorссылке есть конструктор и две функции , в зависимости от того, что лучше соответствует вашим потребностям.
Крис
1
Вы не можете избежать копирования, просто задав начальное значение.
juanchopanza
1
Избегайте копий? Хранение указателей довольно легкое с точки зрения затрат на копирование.
user7116
1
@ Дамир, ты имел ввиду std::vectorв названии?
Robᵩ

Ответы:

181
std::vector<CustomClass *> whatever(20000);

или:

std::vector<CustomClass *> whatever;
whatever.reserve(20000);

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

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

Джерри Гроб
источник
Что из этого было бы более эффективным для большого количества вставок / удалений?
ctor
3
@Loggie: Я сомневаюсь, что будет какая-то разница в эффективности. В основном это меняет то, как вы его используете - с первым вы просто обращаетесь к указателям, что-то вроде того whatever[10000] = somepointer;, где последний требует от вас push_backкаждого добавляемого указателя. По крайней мере, если вы привыкли vector, последнее, вероятно, проще и естественнее.
Jerry Coffin,
Если размер копируемого контейнера известен, почему не более эффективно (изменить) размер, а затем скопировать вместо pushing_back?
1
@Cincinnatus: Потому что у него есть вызов reserve, который предварительно выделяет размер памяти. Теоретически установка размера может происходить на несколько минут быстрее, так как это также позволяет избежать увеличения текущего размера каждый раз, когда вы добавляете элемент. На самом деле я сомневаюсь, что вы сможете это измерить.
Джерри Коффин,
1
на самом деле, если вы делаете это по горячему пути, и код вызывается много, вы можете сделать много инструкций и сэкономить время.
bayindirh
15

Вам нужно использовать функцию резервирования, чтобы установить начальный выделенный размер или сделать это в начальном конструкторе.

vector<CustomClass *> content(20000);

или

vector<CustomClass *> content;
...
content.reserve(20000);

Когда вы создаете reserve()элементы, vectorон выделяет достаточно места (по крайней мере?) Для такого количества элементов. Элементы не существуют в vector, но память готова к использованию. Тогда это, возможно, ускорится, push_back()потому что память уже выделена.


источник
Выделение размера также может быть предоставлено во время строительства путем передачи целочисленного аргумента (например std::vector<Custom Class*> content(100);)
adelbertc
@kstruct: Да, но он может быть менее эффективным - на очень небольшую величину.