Я только что узнал, что std::vector<T>::resize
"удваивает" свою емкость даже при изменении размера до одного элемента выше текущего размера:
std::vector<int> v(50);
v.resize(51);
std::cout << v.capacity() << std::endl;
Эта программа выводит 100 с GCC и Clang и 75 с Visual C++. Однако, когда я переключаюсь с resize
для reserve
:
std::vector<int> v(50);
v.reserve(51);
std::cout << v.capacity() << std::endl;
Выходной сигнал составляет 51 со всеми тремя компиляторами.
Интересно, почему в реализациях используется другая стратегия расширения для resize
и reserve
. Это кажется непоследовательным, и я бы ожидал такого же поведения здесь.
Я просто добавляю ссылку на мотивацию для моего вопроса, где сообщается о влиянии на производительность: почему C++ векторы STL на 1000 раз медленнее при выполнении многих резервов?
Добавление цитаты из C+ +1 1 Стандарт для уточнения требований к reserve
; §23.3.6.3 (2):
После
reserve()
capacity()
больше или равна аргументуreserve
если происходит перераспределение...
Некоторые дополнительные мысли: из C+ +1 1 Стандарт:
Сложность: сложность линейна по количеству вставленных элементов плюс расстояние до конца вектора.
Это, собственно, подразумевает постоянную (амортизированную) сложность для вставки одного элемента в конце. Однако это относится только к векторным модификаторам, таким как push_back
или insert
(§23.3.6.5).
resize
не входит в число модификаторов. Он указан в разделе 23.3.6.3 vector
емкости. И нет требований к сложности для resize
.
Однако в разделе обзора vector
(§23.3.6.1) написано:
он (
vector
) поддерживает (амортизируется) постоянное время вставки и стирания операций в конце
Вопрос в том, является ли resize(size()+1)
"вставкой в конце".