Я предварительно выделяю память для моей vector
переменной-члена. Ниже код минимальная часть
class A {
vector<string> t_Names;
public:
A () : t_Names(1000) {}
};
Теперь в какой-то момент времени, если t_Names.size()
равен 1000
. Я намерен увеличить размер на 100
. Затем, если оно достигнет 1100
, снова увеличьте на 100
и так далее.
У меня вопрос, что выбирать между vector::resize()
а vector::reserve()
. Есть ли лучший выбор в этом сценарии?
Изменить : у меня есть своего рода точная оценка для t_Names
. Я оцениваю это быть рядом 700
с 800
. Однако в определенных (редко) ситуациях он может расти больше, чем 1000
.
std::vector
.Ответы:
Эти две функции делают совершенно разные вещи!
resize()
Метод (и передавая аргумент в конструктор эквивалентно) будет вставить или удалить соответствующее количество элементов в вектор , чтобы сделать его заданный размер (он имеет необязательный второй аргумент , чтобы определить их значение). Это повлияет наsize()
, итерация пройдет по всем этим элементам, push_back вставит после них, и вы можете получить к ним прямой доступ, используяoperator[]
.reserve()
Метод только выделяет память, но оставляет его инициализирован. Это только влияетcapacity()
, но неsize()
изменится. Для объектов нет значения, потому что к вектору ничего не добавлено. Если вы затем вставите элементы, перераспределение не произойдет, потому что это было сделано заранее, но это единственный эффект.Так что это зависит от того, что вы хотите. Если вы хотите массив из 1000 элементов по умолчанию, используйте
resize()
. Если вам нужен массив, в который вы ожидаете вставить 1000 элементов и хотите избежать пары выделений, используйтеreserve()
.РЕДАКТИРОВАТЬ: комментарий Blastfurnace заставил меня снова прочитать вопрос и понять, что в вашем случае правильный ответ не распределяется вручную. Просто продолжайте вставлять элементы в конце, как вам нужно. Вектор будет автоматически перераспределяться по мере необходимости и будет делать это более эффективно, чем упомянутый ручной способ. Единственный случай, когда это
reserve()
имеет смысл, - это когда у вас есть достаточно точная оценка общего размера, которая вам будет легко доступна заранее.РЕДАКТИРОВАТЬ 2: Редактировать вопрос объявления: Если у вас есть начальная оценка, то
reserve()
эта оценка. Если этого окажется недостаточно, просто дайте вектору сделать свое дело.источник
vector
.x.reserve(x.size() + newdata); vector<int>::iterator special_element = get_special_element(x); for (int i = 0; i < newdata; ++i) { if some_function(i, special_element) x.push_back(i); }
довольно надежно с точки зрения резервирования места. Я понятия не имею, сколько элементов на самом деле будет добавлено, но у меня есть верхняя граница. Конечно, когда есть сомнения, с векторами вы можете просто использовать индексы вместо итераторов, разница обычно незначительна.size()
. «Метод reserve () только выделяет память» - он может выделять или не распределять память в зависимости от того,capacity()
достаточно ли он уже, ему также может понадобиться перемещать элементы и освобождать их исходную память. «хочу избежать пары выделений», копий и т. д.resize()
не только выделяет память, но и создает столько экземпляров, сколько и желаемый размер, который вы передаете вresize()
качестве аргумента. Ноreserve()
только выделяет память, он не создает экземпляров. То есть,Выход ( онлайн демо ):
Это
resize()
может быть нежелательно, если вы не хотите создавать объекты по умолчанию. Это будет медленно. Кроме того, если выpush_back()
добавите в него новые элементы,size()
вектор будет еще больше увеличиваться за счет выделения новой памяти (что также означает перемещение существующих элементов во вновь выделенную область памяти). Если вы использовалиreserve()
в начале, чтобы убедиться, что уже достаточно выделенной памяти,size()
вектор будет увеличиваться, когда выpush_back()
к нему, но он не будет выделять новую память снова, пока он не исчерпает пространство, которое вы зарезервировали для него .источник
reserve(N)
мы можем использоватьoperator []
безвредно. верный ?reserve
, спецификация требует, чтобы она выделяла, по крайней мере, столько, поэтому некоторые реализации могут округляться до некоторой границы и, таким образом, показывать более высокую емкость, чем 1000.v.size()
. Обратите внимание, чтоreserve(N)
не меняетсяsize()
вектор.Из вашего описания похоже, что вы хотите «зарезервировать» выделенное пространство для хранения вектора t_Names.
Обратите внимание, что
resize
инициализируйте только что выделенный вектор, которыйreserve
просто выделяет, но не создает. Следовательно, «резерв» намного быстрее, чем «изменение размера»Вы можете обратиться к документации относительно разницы размеров и резерва
источник
резервировать, когда вы не хотите, чтобы объекты инициализировались при резервировании. Кроме того, при изменении размера вы можете предпочесть логически дифференцировать и отслеживать его количество в зависимости от его количества использования. поэтому в интерфейсе есть поведенческая разница - вектор будет представлять то же количество элементов при резервировании и будет на 100 элементов больше при изменении размера в вашем сценарии.
это полностью зависит от ваших целей в борьбе с поведением по умолчанию. некоторые люди предпочтут специализированные распределители, но нам действительно нужно лучше понять, что именно вы пытаетесь решить в своей программе, чтобы дать вам хороший совет.
Между тем, многие векторные реализации просто удваивают количество выделенных элементов, когда они должны расти. Вы пытаетесь минимизировать пиковые размеры выделения или пытаетесь зарезервировать достаточно места для какой-нибудь свободной от блокировки программы или чего-то еще?
источник
operator[]
что-либо.