12 Мая в 07:55
10 +1
0
Ответы
1
Кратко: `v.reserve(101010)` выделяет буфер с capacity ≥ 10\,1010\, но size остаётся 0\,00. При `push_back` память перевыделяется каждый раз, когда size достигает capacity.
Что произойдёт в вашем фрагменте:
- после `v.reserve(101010)` у вас capacity = ≥10\ge 1010, size = 0\,00;
- первые 10\,1010 вызовов `push_back` не вызывают перевыделения;
- 11\,1111-й вызов требует перевыделения в новый буфер с capacity ≥ 11\,1111 (на практике реализация обычно увеличивает capacity экспоненциально — например до 15\,1515 или 20\,2020, но это implementation-defined);
- 12\,1212-й вызов уже поместится в новый буфер без дополнительной аллокации.
Копирования/перемещения:
- при перевыделении все существующие элементы копируются или перемещаются в новый буфер; их число равно предыдущему size (здесь примерно 10\,1010 элементов);
- для тривиальных типов (как `int`) это обычно эквивалентно `memmove` и дешево; для пользовательских типов используются move- или copy-конструкторы;
- если move-конструктор не `noexcept`, реализация может использовать копирование для сохранения гарантий исключений.
Сложности:
- отдельный `push_back` — амортизированно O(1)O(1)O(1), но один перевод/перемещение при перевыделении стоит O(k)O(k)O(k), где kkk — текущий size.
Как оптимизировать добавление большого числа элементов:
- заранее вызвать `v.reserve(N)` с ожидаемым количеством элементов NNN (например `v.reserve(121212)`) — тогда перевыделений не будет;
- альтернативно: `v.resize(N)` и затем заполнять по индексу — избегает проверок роста, но при этом элементы value-initialized;
- использовать `emplace_back` для конструирования элементов прямо в буфере (экономит копии/перемещения);
- при больших вставках использовать `v.insert(v.end(), first, last)` или конструктор из диапазона;
- для типов с дорогой семантикой перемещения — сделать move-конструктор `noexcept`, чтобы при перевыделении использовалось перемещение, а не копирование.
Пример простого исправления вашего фрагмента:
v.reserve(121212);
for (int i = 0; i < 121212; ++i) v.push_back(i);
Это гарантирует отсутствие перевыделений и перемещений при вставке этих 12\,1212 элементов.
12 Мая в 08:01
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир