Страницы

Поиск по вопросам

понедельник, 23 декабря 2019 г.

c++: выделение места под контейнер

#cpp #cpp11 #vector #stl #cpp14


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

std::vector storage;
storage.reserve(10000);


а что происходит, когда я вычищаю элементы из контейнера?

storage.clear();


Нужно ли мне опять зарезервировать объем или можно ли сделать такой clear(), чтобы
осталась зарезервированная память
    


Ответы

Ответ 1



Функция clear не освобождает зарезервированную память. Чтобы она освободилась, нужно после clear вызвать shrink_to_fit.

Ответ 2



Согласно документации по методу std::vector::clear() (вольный перевод): Изменение фактического размера блока памяти не гарантируется, а потому отсутствует и гарантия изменения вместимости вектора. Для принудительного освобождения памяти необходимо использовать swap: vector().swap(x); // высвобождаем память из-под x A reallocation is not guaranteed to happen, and the vector capacity is not guaranteed to change due to calling this function. A typical alternative that forces a reallocation is to use swap: vector().swap(x); // clear x reallocating Причина — дороговизна обращения к диспетчеру памяти. Ведь он должен взять глобальную блокировку, по крайней мере частично пробежаться по списку выделенных блоков и иногда выполнить слияние смежных свободных блоков. Так что можно спокойно закладываться на то, что память повторно резервировать не надо.

Ответ 3



Да, нужно повторно вызывать reserve. После очистки с помощью clear вектор формально считается пустым и вы не должны делать предположений о том что фактически сделал вектор с памятью. Так как стандарт ничего такого не требует и не обещает, то есть вектор может освободить всю память, ее часть или ничего не освобождать. Ничего страшного не произойдет если память не освободится, а вы повторно вызвали reserve. С другой стороны если память освободится, ваш повторный вызов reserve сделает то же что и первый - зарезервирует нужное количество памяти.

Ответ 4



Т.е. из всего вышесказанного все таки выходит, что если работа с контейнером идет постоянно, то можно не особо заморачиваться после вычищения контейнера с резервированием памяти, поскольку старая не отдается системе и может быть использована повторно? Будет тот же эффект, как будто я каждый раз резервирую память, т.е. при операциях добавления элемента лишнее время на выделение памяти под элемент тратиться не будет.

Комментариев нет:

Отправить комментарий