Elegir entre std:: mapa y std:: mapa desordenado


Ahora que std tiene un mapa hash real en unordered_map, ¿por qué (o cuándo) todavía querría usar el viejo map sobre unordered_map en sistemas donde realmente existe? ¿Hay alguna situación obvia que no pueda ver inmediatamente?

Author: emlai, 2010-10-11

5 answers

Como ya se ha mencionado, map permite iterar sobre los elementos de una manera ordenada, pero unordered_map no. Esto es muy importante en muchas situaciones, por ejemplo, mostrar una colección (por ejemplo, una libreta de direcciones). Esto también se manifiesta de otras maneras indirectas como: (1) Comenzar a iterar desde el iterador devuelto por find(), o (2) existencia de funciones miembro como lower_bound().

También, creo que hay alguna diferencia en el peor caso buscar complejidad.

  • Para map, es O( lg N )

  • Para unordered_map, es O( N ) [Esto puede suceder cuando la función hash no es buena, lo que lleva a demasiadas colisiones hash.]

Lo mismo es aplicable para el peor caso deletion complexity.

 100
Author: Arun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:02

Además de las respuestas anteriores, también debe tener en cuenta que solo porque unordered_map es velocidad constante (O(1)) no significa que sea más rápido que map (de orden log(N)). La constante puede ser mayor que log(N) especialmente porque N está limitada por 232 (o 264).

Así que además de las otras respuestas (map mantiene el orden y las funciones hash pueden ser difíciles), puede ser que map sea más eficiente.

Por ejemplo, en un programa que ejecuté para un blog post Vi que para VS10 std::unordered_map era más lento que std::map (aunque boost::unordered_map era más rápido que ambos).

Gráfico de Rendimiento

Note 3rd a 5th bars.

 84
Author: Motti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-21 11:09:00

Esto se debe a Chandler Carruth de Google en su conferencia CppCon 2014

std::map es (considerado por muchos como) no útil para el trabajo orientado al rendimiento: Si desea O (1) - acceso amortizado, use una matriz asociativa adecuada (o por falta de una, std::unorderded_map); si desea un acceso secuencial ordenado, use algo basado en un vector.

También, std::map es un árbol equilibrado; y tienes que atravesarlo, o reequilibrarlo, increíblemente a menudo. Estos son asesinos de caché y cache-apocalypse operations respectivamente... así que di NO a std::map.

Podría interesarle esta pregunta sobre implementaciones eficientes de mapas hash.

(PS - std::unordered_map es hostil a la caché porque usa listas enlazadas como cubos.)

 22
Author: einpoklum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:39

Creo que es obvio que usaría el std::map que necesita para iterar entre los elementos del mapa en orden ordenado.

También puede usarlo cuando prefiera escribir un operador de comparación (que es intuitivo) en lugar de una función hash (que generalmente es muy poco intuitiva).

 21
Author: Ken Bloom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-10 23:32:06

Digamos que tienes teclas muy grandes, quizás cadenas grandes. Para crear un valor hash para una cadena grande, debe recorrer toda la cadena de principio a fin. Tomará al menos tiempo lineal hasta la longitud de la clave. Sin embargo, cuando solo busca un árbol binario usando el operador > de la clave, cada comparación de cadenas puede devolverse cuando se encuentra el primer desajuste. Esto es típicamente muy temprano para cuerdas grandes.

Este razonamiento se puede aplicar a la función find de std::unordered_map y std::map. Si la naturaleza de la clave es tal que se necesita más tiempo para producir un hash (en el caso de std::unordered_map) que para encontrar la ubicación de un elemento mediante búsqueda binaria (en el caso de std::map), debería ser más rápido buscar una clave en el std::map. Es bastante fácil pensar en escenarios en los que este sería el caso, pero creo que serían bastante raros en la práctica.

 7
Author: Martin G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-19 20:22:45