Какой самый быстрый способ очистить std :: список динамических объектов? - PullRequest
2 голосов
/ 23 февраля 2012

У меня есть список, определенный как:

std::list<int *> m_ilist;

, и я добавляю int s в список:

m_ilist.push_back (new int (x));

Я хочу уничтожить вектор и удалить память, котораябыл выделен для каждого элемента.

Какой из них лучше:

  1. Выполнение цикла по списку с вызовом delete для каждого итератора.После этого вызова clear ():

    for (...) { delete *it; } m_ilist.clear ();
    
  2. Выполнение цикла, но вызов стирания на итераторе:

    for (...) { delete *it; m_ilist.erase (); }
    

Лучше будет определяться как более быстрая / быстрая / меньшая обработка.

Спасибо.

Ответы [ 2 ]

1 голос
/ 23 февраля 2012

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

Вы можете попытаться объединить целые числа.Вместо выделения и освобождения целых чисел создайте пул целых чисел.Это избавляет вас от необходимости снова и снова выделять и освобождать память за счет выполнения собственного управления (какие целые числа уже используются, а какие нет).Насколько это сложное управление, зависит от ситуации.В некоторых случаях достаточно просто раздать целые числа одно за другим и удалить их все в конце.Посмотрите, может ли этот трюк помочь в вашем случае.

Вы также можете попытаться очистить список не в главном потоке, а в отдельном потоке.Запустите «поток очистки» в начале вашего приложения, и когда список должен быть очищен, передайте список другому потоку (используйте события, критические секции и очередь для передачи списка из основного потока в очистку).Теперь поток очистки может очистить список и освободить память, пока основной поток продолжает выполнять важные действия.

Наконец, используйте свое воображение.

1 голос
/ 23 февраля 2012

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

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

Сказав это; Разница, скорее всего, незначительна, так что моя интуиция говорит, что идите на секунду и сохраните один цикл, если сомневаетесь.


Изменить: Обратите внимание, что если вы действительно беспокоитесь о скорости, используйте std::vector<int> вместо std::list<int*>. Разница будет значительно больше, чем между перечисленными вами опциями.

Редактировать 2: Если вы используете std::vector, обязательно используйте вариант 1 (с clear вместо многих erase с). В этом случае действительно имеет огромное значение. Если элементы действительно огромные (в отличие от int), вы можете захотеть поместить указатели (или умные указатели, в этом отношении) в вектор, чтобы минимизировать накладные расходы на копирование.

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