Использовать ли экземпляры класса или std :: shared_ptr - PullRequest
0 голосов
/ 22 января 2019

У меня есть карта, в которой хранятся атаки для разных портов. Теперь я озадачен тем, как хранить детали атаки в качестве значения. Также может быть несколько атак для одного порта.

AttackDetails - это структура, содержащая различные детали каждой атаки.

Теперь у меня есть два подхода к карте:

std::map <int, std::list<AttackDetails>>
std::map <int, std::list<<std::shared_ptr<AttackDetails>>>

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

Мне нужно получить доступ к списку при удалении деталей атаки, где мне нужно будет пройти по списку и найти аналогичный идентификатор атаки и остановить эту конкретную атаку.

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Поскольку вам, кажется, просто нужны AttackDetails сами , а не только те, чьи времена жизни управляются семантикой RAII, я думаю, что

std::map<int, std::list<AttackDetails>>

будет более предпочтительным, чем std::map<int, std::list<<std::shared_ptr<AttackDetails>>>.

Подобные понятия изложены в R.30 из C ++ Core Guidelines следующим образом. Хотя это не совсем та же ситуация с текущей проблемой, но эту точку зрения следует разделить с нами:

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

Причина Принятие умного указателя на виджет неправильно, если функции нужен только сам виджет. Он должен быть в состоянии принять любой объект виджета, а не только тот, чьи времена жизни управляются определенным видом интеллектуального указателя. Функция, которая не управляет временем жизни, должна вместо этого использовать необработанные указатели или ссылки.


... есть ли лучшее решение?

  • Используйте std::unordered_map, если вам не нужно сортировать элементы по ключу.

  • Элементы std::list разбросаны по памяти. Следовательно, именно операции доступа обычно приводят к отсутствию кэша и показывают низкую производительность. Даже если удаление какого-либо одного из них с помощью std::list::erase имеет сложность O (1), производительность доступа значительно ниже, а иногда имеет смысл использовать другие контейнеры STL. Я рекомендую вам проверить производительность и сравнить результаты между std::list, std::vector и std::deque.

0 голосов
/ 22 января 2019

Вам нужно общее владение экземпляра AttackDetails? Если нет, то вы не должны использовать std::shared_ptr.

Если вы хотите оптимизировать производительность поиска, рассмотрите возможность использования структуры хэш-данных, такой как unordered_map (или более быстрое стороннее решение), поскольку это снизит вашу сложность с O(log N) до O(1).

...