Як встановити початковий розмір std :: vector?


130

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


1
У будь- std::vectorякій довідці є конструктор і дві функції для цього , залежно від того, що краще відповідає вашим потребам.
chris

1
Ви не можете уникнути копіювання, просто встановивши початкове значення.
juanchopanza

1
Уникайте копій? Зберігання покажчиків досить легке з точки зору вартості копіювання.
user7116


1
@Damir, ти мав std::vectorна увазі в назві?
Robᵩ

Відповіді:


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

або:

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

Перший встановлює фактичний розмір масиву - тобто робить його вектором 20000 покажчиків. Останній залишає вектор порожнім, але залишає простір для 20000 покажчиків, тож ви можете вставити (до) стільки, скільки без нього потрібно перерозподіляти.

Принаймні, з мого досвіду, досить незвично для будь-якого з них важливо змінити продуктивність - але це може вплинути на правильність за певних обставин. Зокрема, доки не відбудеться перерозподіл, ітератори у вектор гарантовано залишаться дійсними, і щойно ви встановите розмір / зарезервований простір, ви гарантовано не матимете перерозподілу, доки ви не зробите це " t збільшити розмір понад це.


Яке з них було б більш ефективним для великої кількості вставок / видалень?
ctor

3
@Loggie: Я сумніваюся, що буде різниця в ефективності. Переважно це змінює спосіб його використання - з першим ви просто звертаєтесь до вказівників, тож щось на зразок whatever[10000] = somepointer;, коли останні вимагають від вас push_backкожного введеного вами вказівника. Принаймні, якщо ви звикли vector, останні, мабуть, простіші та природніші.
Джеррі Труну

Якщо розмір контейнера, з якого копіюється, відомий, чому він не є більш ефективним для (повторного) розміру та копіювання замість push_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: Так, але це може бути менш ефективно - дуже невеликою кількістю.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.