web-dev-qa-db-fra.com

Comment choisir entre map et unordered_map?

Supposons que je veuille mapper les données avec une chaîne comme clé. Quel conteneur devrais-je avoir choisi, map ou unordered_map? unordered_map utilise plus de mémoire, alors supposons que la mémoire ne soit pas un problème et que le problème soit la vitesse.

unordered_map devrait généralement donner une complexité moyenne de O(1) avec le pire cas de O (n). Dans quels cas cela arriverait-il à O (n)? Quand un map gagne plus de temps que unordered_map? Cela arrive-t-il quand n est petit?

En supposant que je voudrais utiliser STL unordered_map avec la valeur par défaut Vs. carte. la chaîne est la clé.

Si je vais parcourir les éléments plutôt que d'accéder à un élément individuel à chaque fois, devrais-je préférer map?

73
StackHeapCollision

En pratique, si la mémoire n’est pas un problème, unordered_map est toujours plus rapide si vous souhaitez accéder à un seul élément.

Le pire des cas est théorique et lié à un seul hachage représentant tous les éléments. Ce n'est pas d'une pertinence pratique. Le unordered_map ralentit dès que vous avez au moins log N éléments appartenant au même hash. Cela n’a pas non plus de pertinence pratique. Dans certains scénarios spéciaux, vous pouvez utiliser un algorithme de hachage spécifique qui garantit une distribution plus uniforme. Pour les chaînes ordinaires qui ne partagent pas un modèle spécifique, les fonctions de hachage génériques fournies avec unordered_map sont tout aussi bien.

Si vous souhaitez parcourir la carte (à l'aide d'itérateurs) de manière triée, vous ne pouvez pas utiliser unordered_map. Au contraire, map permet non seulement cela, mais peut également vous fournir l'élément suivant d'une carte basée sur une approximation de la clé (voir lower_bound et upper_bound méthodes).

56
ypnos
                       | 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| 
183
user1773602

Dans quels cas cela arriverait-il à O (n)?

si vous avez une telle fonction de hachage mauvaise qui produit la même valeur de hachage pour tous les brassages d'entrée (c'est-à-dire produire des collisions) ...

Quel conteneur devrais-je avoir choisi, map ou unordered_map?

Ce sont toujours les questions de besoins et de type/quantité de données que vous avez.

Quand une carte obtient-elle plus de temps que l'unordered_map?

Ce ne sont que des structures différentes. Vous feriez mieux de choisir d'utiliser l'une d'entre elles en fonction de vos cas d'utilisation typiques (en tenant compte du type de données dont vous disposez et de leur quantité).

Est-ce que hppaen quand n est petit?

Dans le cas de petites quantités de données, tout dépend de la mise en oeuvre de la STL ... Ainsi, même un vecteur/tableau simple peut parfois être plus rapide que des conteneurs associatifs ...

7
zaufi

Quel conteneur devrais-je avoir choisi, map ou unordered_map? unordered_map utilise plus de mémoire, alors supposons que la mémoire ne soit pas un problème et que le problème soit la vitesse.

Profil et ensuite décider. unordered_map est généralement plus rapide, mais cela varie selon les cas.

Dans quels cas cela arriverait-il à O (n)?

Lorsque le hachage n'est pas bon et qu'un tas d'éléments sont assignés aux mêmes bacs.

Quand une carte obtient-elle plus de temps que l'unordered_map? Est-ce qu'il se passe quand n est petit?

Probablement pas, mais profilez-le si vous y tenez. Avoir un conteneur de petite taille constituant le goulot d'étranglement de votre programme semble extrêmement improbable. Quoi qu'il en soit, un simple vector avec recherche linéaire peut être plus rapide dans de tels cas.


La chose la plus importante en décidant est les conditions de la commande et l'absence d'invalidation d'itérateur. Si vous avez besoin de l’un ou de l’autre, vous devez utiliser map. Autrement, unordered_map.

7
Pubby