Предположим, я хотел отобразить данные со строкой в качестве ключа.
Какой контейнер следует выбрать, map
или unordered_map
? unordered_map
занимает больше памяти, поэтому допустим, что память не является проблемой, и проблема в скорости.
unordered_map
обычно должна давать среднюю сложность O (1) с наихудшим случаем O (n).
В каких случаях он достигнет O (n)?
Когда map
получает больше времени, чем unordered_map
? Это случается, когда n мало?
Предполагая, что я буду использовать STL unordered_map
со значением по умолчанию haser Vs. карта. строка - это ключ.
Если я собираюсь итерации по элементам, а не доступа к отдельному элементу каждый раз, предпочитаю ли я map
?
Ответ 1
На практике, если память не проблема, unordered_map
всегда быстрее, если вы хотите получить один элемент.
Худший случай теоретический и связан с одним хешем, учитывающим все элементы. Это не имеет практического значения. unordered_map
замедляется, как только у вас есть хотя бы log N элементов, принадлежащих к одному и тому же хэшу. Это также не имеет практического значения. В некоторых специальных сценариях вы можете использовать специальный алгоритм хэширования, который обеспечивает более равномерное распределение. Для обычных строк, которые не имеют определенного шаблона, общие хэш-функции, идущие с unordered_map
, также хороши.
Если вы хотите отсортировать карту (используя итераторы) отсортированным способом, вы не можете использовать unordered_map
. Наоборот, map
не только позволяет это, но также может предоставить вам следующий элемент на карте, основанный на аппроксимации ключа (см. Методы lower_bound
и upper_bound
).
Ответ 2
| map | unordered_map
---------------------------------------------------------
element ordering | strict weak | n/a
| |
common implementation | balanced tree | hash table
| or red-black tree|
| |
search time | log(n) | O(1) if there are no hash collisions
| | Up to O(n) if there are hash collisions
| | O(n) when hash is the same for any key
| |
Insertion time | log(n)+rebalance | Same as search
| |
Deletion time | log(n)+rebalance | Same as search
| |
needs comparators | only operator < | only operator ==
| |
needs hash function | no | yes
| |
common use case | when good hash is| In most other cases.
| not possible or |
| too slow. Or when|
| order is required|
Ответ 3
В каком контейнере я должен выбрать, карту или unordered_map? unordered_map занимает больше памяти, поэтому пусть память не является проблемой, и проблема заключается в скорости.
Профиль, а затем решите. unordered_map
, как правило, быстрее, но он меняется в каждом случае.
В каких случаях он мог бы добраться до O (n)?
Когда хеширование не является хорошим, и куча элементов присваивается тем же ячейкам.
Когда карта получает больше времени, чем unordered_map? Означает ли это, когда n мало?
Наверное, нет, но профиль, если вы действительно заботитесь. Наличие контейнера с небольшим размером является узким местом вашей программы, кажется крайне маловероятным. Во всяком случае, простой vector
с линейным поиском может быть быстрее для таких случаев.
Самое главное при принятии решения - требования к порядку и отсутствие аннулирования итератора. Если вам тоже нужно, вы должны использовать map
. В противном случае unordered_map
.
Ответ 4
В каких случаях он достигнет O (n)?
если у вас есть такая хеш-функция bad, которая создает одно и то же значение хэша для всех перемещений ввода (т.е. создает коллизии)...
В каком контейнере я должен выбрать, отобразить карту или unordered_map?
У вас всегда есть вопросы, касающиеся требований и вида/объема данных.
Когда карта получает больше времени, чем unordered_map?
Это просто разные структуры. Вам лучше сделать выбор, чтобы использовать один из них в зависимости от ваших типичных случаев использования (принимая во внимание, какие данные у вас есть и его количество)
Это hppaen, когда n мало?
В случае небольшого количества данных все зависит от конкретной реализации STL...
Поэтому иногда даже простой вектор/массив может быть быстрее, чем ассоциативные контейнеры...