Чистый вектор на каждой итерации цикла. Какой самый эффективный способ памяти? - PullRequest
5 голосов
/ 06 марта 2009

У меня вопрос по поводу std :: vector.

У меня очень ресурсоемкий алгоритм, в котором я прогнозирую, что прогнозирование размеров векторов и предварительное резервирование памяти для векторов мне очень поможет в сокращении использования памяти.

Что из перечисленного лучше:

for ( ... ) {
  std::vector<Type> my_vector;
  my_vector.reserve(stuff_count);
  // Do stuff , and append stuff to my_vector.
}

Или это:

std::vector my_vector;
for ( ... ) {
  my_vector.clear();
  my_vector.reserve(stuff_count);
  // Do stuff , and append stuff to my_vector.
}

Пожалуйста, скажите мне, какой из них лучше, или если есть еще лучший способ сделать что-то.

Заранее большое спасибо!

Ответы [ 9 ]

11 голосов
/ 06 марта 2009

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

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

6 голосов
/ 06 марта 2009

Я предполагаю, что прогнозирование размеров векторов и резервирование достаточного количества памяти для векторов заранее помогут мне значительно сократить использование памяти.

Попробуй действовать как инженер, а не как гадалка. Создайте тест и измерьте разницу.

5 голосов
/ 06 марта 2009

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

5 голосов
/ 06 марта 2009

Второй может быть немного быстрее, но я нахожу первый чище.

1 голос
/ 10 марта 2009

Второй будет использовать максимальный объем памяти всех циклов его использования, то есть максимальный размер типов stuff_count. std::vector::clear() не обязательно освобождает память . То есть, если вы вызываете std::vector::capacity() до и после std::vector::clear(), стандартная соответствующая реализация может вернуть одно и то же значение.

В лучшем случае вы сократите количество раз, которое вы выделяете память с помощью вышеуказанной схемы. Но вы, конечно, не будете уменьшать объем памяти в любой момент. Если вы хотите сжать до зарезервированного объема памяти, вы должны использовать векторную подстановку:

std::vector<type>().swap(my_vector);
my_vector.reserve(stuff_count); 

Или ваше первое решение, поскольку общий эффект будет таким же.

1 голос
/ 06 марта 2009

... резервирование достаточного количества памяти для векторы заранее мне очень помогут с уменьшением использования памяти

эээ ... что ?! Это не имеет никакого смысла. Резервирование памяти никоим образом не помогает уменьшить использование памяти. Это устраняет необходимость в постоянном перераспределении, что ускоряет процесс, но при использовании вы не получаете никакой выгоды.

1 голос
/ 06 марта 2009

Я бы сказал, что это зависит от того, как должен быть построен / уничтожен Type. Если это POD, который не требует уничтожения, вы можете пропустить clear (), которая вызывает все деструкторы в цикле, и использовать его вместо статического массива:

std::vector<Type> my_vector(size);
for (...)
{
  int index = 0;
  // Do stuff
  my_vector[index] = some_value;
}

(Предупреждение: код не проверен)

0 голосов
/ 06 марта 2009

как насчет?

std::vector<DataType> my_vector;
my_vector.resize(sizeof(yourData));
memcpy(reinterpret_cast<char*>(&my_vector), &yourData, sizeof(yourData));
0 голосов
/ 06 марта 2009

Если вам нужно выполнить много добавлений, используйте std :: deque вместо std :: vector и просто используйте push_back.

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