У меня есть следующая проблема. У меня есть игра, которая работает в среднем 60 кадров в секунду. Каждому кадру мне нужно хранить значения в контейнере и не должно быть дубликатов.Какой контейнер хранит уникальные значения?
Возможно, он хранит менее 100 элементов на фрейм, но количество вставных вызовов будет намного больше (и многие из них отклоняются из-за того, что он должен быть уникальным). Только в конце рамки мне нужно пройти контейнер. Таким образом, около 60 итераций контейнера за кадр, но еще больше вставок.
Имейте в виду, что предметы для хранения - простые целые числа.
Есть куча контейнеров, которые я могу использовать для этого, но я не могу решить, что выбрать. Для этого ключевой проблемой является производительность.
Некоторые плюсы/минусы, которые я собрал:
вектор
- (PRO): Contigous памяти, огромный фактор.
- (PRO): память может быть зарезервирована вначале, очень мало выделений/освобождений после этого
- (CON): Нет альтернативы, чтобы пересечь контейнер (std :: find), каждая вставка(), чтобы найти уникальные ключи? Сравнение прост, хотя (целые) и весь контейнер, вероятно, может поместиться кэшированные
набор
- (PRO): Простой, очевидно, имел в виду для этого
- (CON): Не постоянное время вставки
- (CON): Атрибуты распределения/освобождения на фрейм
- (CON): Небезразличная память. Перемещение множества сотен объектов означает прыжок вокруг много в памяти.
unordered_set
- (PRO): Простой, очевидно, имел в виду для этого
- (PRO): Средний случай постоянная времени вставки
- (CON): Видя, как хранить целые числа, хеш-операция, вероятно, намного дороже, чем что-либо еще
- (CON): Атрибуты распределения/освобождения на фрейм
- (CON): Не сопутствующая память. Перемещение множества сотен объектов означает прыжок вокруг много в памяти.
Я склоняюсь идти вектор-маршрут из моделей доступа памяти, даже если набор явно имел в виду эту проблему. Большая проблема, которая для меня непонятна, заключается в том, является ли перемещение вектора для каждой вставки более дорогостоящим, чем распределение/освобождение (особенно учитывая, как часто это нужно делать) и поиск в памяти набора.
Я знаю, что в конечном итоге все сводится к профилированию каждого случая, но если не что иное, как головной план или только теоретически, что, вероятно, было бы лучше всего в этом сценарии? Есть ли какие-либо плюсы и минусы, которые я, возможно, пропустил?
EDIT: Как я не упоминаю, контейнер очищается() в конце каждого кадра
*** Просто измерить *** Учитывая, что 'unordered_set' есть ** функцию ** классический "набор" контейнер с неупорядоченным-нет дубликатов семантики и лучшая асимптотическая сложность, я бы дал ему шанс, но вероятность того, что 'vector' будет бить его за небольшие размеры контейнеров, так как он обладает гораздо лучшими свойствами локальности кэша. –
Как насчет предоставления собственного распределителя, который способен преодолеть неэффективность управления памятью? (например, предоставление пула объектов) –
Независимо от того, что вы делаете, попробуйте правильно инкапсулировать свой код и использовать 'auto' для отслеживания типов, чтобы вы могли легко изменить свой выбор контейнера в будущем. Затем измерьте. –