Стоит ли беспокоиться о фрагментации памяти с помощью std :: vector? - PullRequest
6 голосов
/ 31 октября 2011

Стоит ли беспокоиться о фрагментации памяти с помощью std :: vector? Если так, есть ли способы помочь предотвратить это? Я не всегда предсказываю, чтобы мои программы работали на ПК, они также могут работать на встроенных устройствах / игровых приставках, поэтому я не всегда смогу полагаться на виртуальную память.

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

Спасибо за любой совет!

Ответы [ 6 ]

11 голосов
/ 31 октября 2011

Ответом на ваши заботы может быть std::deque. Он дает вам интерфейс, аналогичный интерфейсу std::vector, но лучше работает с фрагментированной памятью, поскольку он выделяет несколько маленьких массивов вместо большого. Это на самом деле менее эффективно, чем std::vector в некоторых аспектах, но для вашего случая это может быть хорошим компромиссом.

5 голосов
/ 31 октября 2011

Если ваш вектор будет перераспределяться много раз, то да, это может привести к фрагментации памяти.Самый простой способ избежать этого - использовать std :: vector :: reserve () , если вы более или менее знаете, насколько велик может расти ваш массив.

Вы также можете рассмотреть возможность использования std :: deque вместо вектора, так что у вас вообще не будет проблем с фрагментацией памяти.

Вот тема стекового потока, которая может быть вам интересна: what-is-память-фрагментации .

3 голосов
/ 31 октября 2011

std :: vector хорош только как новый. Он просто обрабатывает выделение памяти для вас Несколько вещей, которые вы можете сделать - при условии, что вы не хотите писать совершенно новый новый обработчик.

Предварительно выделите векторы или измените размер (), если вы знаете, каким будет конечный размер, это останавливает расточительные копии памяти по мере их роста.

Если вы собираетесь снова использовать вектор с тем же размером, лучше сохранить его и заполнить, чем удалить и воссоздать его.

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

2 голосов
/ 31 октября 2011

Один хороший способ минимизировать повторные вызовы выделения и перераспределения памяти с помощью std::vector - это свободно использовать std::vector::reserve(), если у вас есть представление о том, сколько элементов будет использовать ваш вектор.Это предварительно выделит емкость и предотвратит изменение размера внутреннего массива, который поддерживает вектор, когда вы добавляете элементы через push_back().

2 голосов
/ 31 октября 2011

Вы всегда должны беспокоиться о производительности и эффективности , когда ваш профилировщик говорит вам об этом (вы можете быть этим профилировщиком, но вы должны «измерять», а не догадываться).

Что вы можете сделать:

  1. Предварительно выделить емкость:

     std::vector<int> x(1000); // size() is 1000
    
     std::vector<int> y;
     y.reserve(1000); // size() is 0, capacity is 1000
    
  2. использовать собственный распределитель

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

Для профилирования кучи я предлагаю

1 голос
/ 31 октября 2011

Нет, std :: vector гарантирует непрерывное хранение. Вы можете использовать vector :: reserve (), чтобы избежать перераспределений при увеличении размера вектора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...