Wybór pomiędzy std:: map a std:: unordered map

Teraz, gdy std ma prawdziwą mapę hashową w unordered_map, Dlaczego (lub kiedy) nadal chciałbym używać starego, dobrego map nad unordered_map na systemach, w których faktycznie istnieje? Czy są jakieś oczywiste sytuacje, których nie mogę od razu zobaczyć?

Author: emlai, 2010-10-11

5 answers

Jak już wspomniano , map pozwala na iterację elementów w sposób posortowany, ale unordered_map tego nie robi. Jest to bardzo ważne w wielu sytuacjach, na przykład wyświetlanie kolekcji (np. książki adresowej). Przejawia się to również w inny pośredni sposób, jak: (1) Rozpoczęcie iteracji od iteratora zwracanego przez find(), lub (2) istnienie funkcji członkowskich, takich jak lower_bound().

Myślę też, że jest jakaś różnica w najgorszym przypadku Szukaj złożoność.

  • Dla map, jest O (lg N )

  • Dla unordered_map, Jest O (N) [to Może zdarzyć się, gdy funkcja hash nie jest dobra, co prowadzi do zbyt wielu kolizji hash.]

To samo dotyczy najgorszego przypadku delecja

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:02

Oprócz powyższych odpowiedzi należy również zauważyć, że to, że unordered_map jest stałą prędkością (O(1)) nie oznacza, że jest szybsza niż map (rzędu log(N)). Stała może być większa niż log(N), zwłaszcza że N jest ograniczona przez 232 (lub 264).

Więc oprócz innych odpowiedzi (map utrzymuje porządek i funkcje hashowe mogą być trudne) może być tak, że map jest bardziej wydajna.

Na przykład w programie, który uruchomiłem dla bloga post widziałem, że dla VS10 std::unordered_map był wolniejszy od std::map (chociaż boost::unordered_map był szybszy od obu).

Wykres Wydajności

Uwaga od trzeciego do piątego taktu.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 11:09:00

jest to spowodowane Chandler Carruth Google w jego CppCon 2014 wykład

std::map jest (przez wielu uważane za) bezużyteczne dla pracy zorientowanej na wydajność: jeśli chcesz o (1)-zamortyzowanego dostępu, użyj odpowiedniej tablicy asocjacyjnej (lub z braku jednej, std::unorderded_map); jeśli chcesz posortowanego dostępu sekwencyjnego, użyj czegoś opartego na wektorze.

Również, std::map jest zrównoważonym drzewem; i trzeba go przemierzać, lub ponownie balansować, niewiarygodnie często. Są to Cache-killer i operacje cache-apocalypse... więc powiedz Nie std::map.

Może Cię zainteresować to pytanie na temat wydajnych implementacji map hashowych.

(PS - std::unordered_map jest Cache-nieprzyjazny, ponieważ używa połączonych list jako wiadra.)

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:39

Myślę, że to oczywiste, że używasz std::map musisz iterację między elementami na mapie w porządku posortowanym.

Możesz go również użyć, gdy wolisz napisać operator porównania (który jest intuicyjny) zamiast funkcji skrótu (która jest ogólnie bardzo nieintuicyjna).

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-10 23:32:06

Powiedzmy, że masz bardzo duże klawisze, być może duże struny. Aby utworzyć wartość skrótu dla dużego ciągu, musisz przejść przez cały łańcuch od początku do końca. To zajmie co najmniej liniowy czas do długości klucza. Jednakże, gdy przeszukujesz tylko drzewo binarne używając operatora > klucza, każde porównanie łańcuchów może zwrócić, gdy zostanie znaleziona pierwsza niezgodność. Jest to zazwyczaj bardzo wcześnie dla dużych strun.

To rozumowanie można zastosować do find funkcji std::unordered_map i std::map. Jeśli charakter klucza jest taki, że wytworzenie skrótu zajmuje więcej czasu (w przypadku std::unordered_map) niż znalezienie lokalizacji elementu za pomocą wyszukiwania binarnego( w przypadku std::map), powinno być szybsze wyszukanie klucza w std::map. Dość łatwo jest myśleć o scenariuszach, w których miałoby to miejsce, ale w praktyce byłyby one dość rzadkie.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-19 20:22:45