Контейнер C++ STL ::clear ::swap

Какой самый быстрый способ «очистить» большой контейнер STL? В моем приложении мне нужно иметь дело с большим размером std::map, например, 10000 элементов.

Я протестировал следующие 3 метода, чтобы очистить файл std::map.

  • Создавайте новый контейнер каждый раз, когда мне это нужно.
  • Вызов метода map::clear().
  • Вызов метода map::swap().

Кажется, что ::swap() дает лучший результат. Кто-нибудь может объяснить, почему это так, пожалуйста? Можно ли с уверенностью сказать, что использование метода map::swap() является правильным способом «очистить» std::map? То же самое для других контейнеров STL, например, set, vector, list и т. д.

    m_timer_start = boost::posix_time::microsec_clock::local_time();

//  test_map.clear();
    test_map.swap(test_map2);
    for (int i = 0; i< 30000; i++){
        test_map.insert(std::pair<int, int>(i, i));
    }    

//  std::map<int, int> test_map_new;
//  for (int i = 0; i< 30000; i++){
//      test_map_new.insert(std::pair<int, int>(i, i));
//  }     

    m_timer_end = boost::posix_time::microsec_clock::local_time();
    std::cout << timer_diff(m_timer_start, m_timer_end).fractional_seconds() << std::endl; // microsecond

person 2607    schedule 10.04.2012    source источник
comment
Самый быстрый почти всегда зависит от реализации.   -  person ildjarn    schedule 11.04.2012
comment
Насколько велика была разница между этими тремя? Если это не так много, я бы сказал, что Clear останется наиболее читаемым.   -  person chris    schedule 11.04.2012
comment
Как вы используете std::swap и как вы это оцениваете?   -  person David Brown    schedule 11.04.2012
comment
Для 30000 элементов std::map с использованием map::clear() требуется около 15 миллисекунд по сравнению с примерно 10 миллисекундами, если используется map::swap(). Спасибо.   -  person 2607    schedule 11.04.2012
comment
swap сам по себе, безусловно, быстрее, чем clear, но он не освобождает место. Вы уверены, что засчитали уничтожение объекта, с которым поменялись местами?   -  person leftaroundabout    schedule 11.04.2012
comment
Вы должны использовать более крупные тестовые случаи. Разница в 5 миллисекунд минимальна.   -  person mfontanini    schedule 11.04.2012
comment
Нам [вам] нужно более полно определить, что вы подразумеваете под словом «клир». Просто сообщить системе, что память можно использовать повторно? Установка каждого пробела в какой-то нулевой элемент? и Т. Д.   -  person prelic    schedule 11.04.2012
comment
Спасибо всем за ваш добрый ответ. Я новичок в программировании на С++, думаю, я ищу «стандартный» способ делать определенные вещи. Спасибо.   -  person 2607    schedule 11.04.2012
comment
@ 2607 : идиоматическим способом будет std::map<int, int>().swap(test_map);.   -  person ildjarn    schedule 11.04.2012
comment
Вы используете map<int,int>. Посмотрите, можете ли вы вместо этого использовать отсортированный вектор; это, безусловно, сделает clear быстрее.   -  person Potatoswatter    schedule 11.04.2012
comment
@ildjarn: Ну, идиоматическим способом было бы использовать .clear(), замена на пустую карту не идиоматична ...   -  person ShadowRanger    schedule 18.04.2016


Ответы (2)


Вы неправильно тестируете случай swap. Вам нужно, чтобы карта swap-to была уничтожена, чтобы учитывать все время. Попробуйте один из них:

{ std::map<something, something_else> test_map2;
test_map.swap(test_map2);
} // test_map2 gets destroyed at the closing brace.

or

// temporary gets destroyed at the semi-colon
std::map<int, int>().swap(test_map);
person Robᵩ    schedule 10.04.2012

Вы спрашиваете об этом, потому что у вас проблемы с производительностью, и вы определили, что ваша программа тратит слишком много времени на очистку ваших карт? Если вы этого не сделали, просто используйте map::clear() или каждый раз создавайте новые локальные переменные, в зависимости от того, что наиболее естественно и прямо для вашей программы. Трюк с подкачкой — это оптимизация, и нет смысла тратить время на оптимизацию, если вы не уверены, что вам это нужно, основываясь на опыте.

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

person bames53    schedule 10.04.2012
comment
Хороший ответ. Однако трюка с обменом нет: см. Ответ Роба. - person Neil G; 11.04.2012
comment
Я думаю, что оптимизация подкачки обычно означает подкачку вместо назначения (копирования), когда содержимое контейнера, из которого поступают данные, впоследствии не имеет значения. Хотя этот трюк чаще всего заменяется на std::move в C++11. - person Thorbjørn Lindeijer; 19.07.2017