2010-02-03 167 views

回答

119

它們以非常不同的方式實現。

hash_mapunordered_map在TR1和Boost中;用它們代替)使用散列表,其中密鑰被散列到表中的一個槽中,並且該值存儲在與該密鑰相關的列表中。

map實現爲平衡二叉搜索樹(通常是紅/黑樹)。

unordered_map應該爲訪問集合的已知元素提供稍好的性能,但map將具有其他有用的特性(例如,它以按排序順序存儲,允許從開始到結束遍歷)。 unordered_map的插入和刪除速度比map快。

+7

我不完全同意你的表現。性能受到很多參數的影響,我會斥責任何使用unordered_map的程序員僅僅爲10個條目,因爲「速度更快」。首先擔心接口/功能,稍後再考慮性能。 – 2010-02-03 14:05:55

+22

好的,如果你瞭解你的問題,這會有所幫助。達到某個數量級時,這可能是一種清洗性能的方式,但瞭解兩個容器的性能特徵非常重要,因爲數據量越來越大,它們會以不同的方式偏離。 – Joe 2010-02-03 15:07:23

+7

有趣的是,我只是在一個應用程序中用一個boost :: unordered_map替換了一個std :: map,在這個應用程序中我進行了大量的隨機查找,並且遍歷了map中的所有鍵。我在查找時節省了大量時間,但通過迭代獲得了回來,所以我切換回地圖並正在尋找其他方法來提高應用程序性能。 – 2010-09-06 21:36:06

4

C++規範並沒有明確說明您必須使用哪種算法來處理STL容器。但是,它確實會對其性能施加一定的限制,從而排除了map和其他關聯容器的哈希表的使用。 (它們通常用紅色/黑色樹來實現。)這些約束要求這些容器比散列表可以提供更好的最差情況。

然而,許多人確實需要散列表,所以基於散列的STL關聯容器已經成爲多年來的常見擴展。因此,他們將unordered_map等添加到更高版本的C++標準中。

+0

它實際上被添加到TR1(std :: tr1 :: unordered_map),而不是C++ 0x – 2010-02-03 05:22:17

+0

編輯修復它。 – 2010-02-03 05:29:07

+0

我認爲'map'一般是一個平衡樹,是因爲使用'operator <()'作爲確定位置的方法。 – KitsuneYMG 2010-02-03 06:26:54

33

hash_map是許多庫實現提供的常見擴展。這正是爲什麼當它作爲TR1的一部分添加到C++標準中時,它被重命名爲unordered_map。地圖通常使用像紅黑樹這樣的平衡二叉樹來實現(實現方式各不相同)。通常使用散列表來實現hash_mapunordered_map。因此訂單不被維護。 unordered_map插入/刪除/查詢將是O(1)(常數時間)其中映射將是O(log n)其中n是數據結構中項目的數量。所以unordered_map是更快,如果你不關心的項目的順序應優先於map。有時候你想要維護秩序(按鍵排序),因此map將是您的選擇。

+9

我想指出的是,當碰撞可能發生時,散列映射具有O(N)的最壞情況訪問(壞散列fcn,加載因子太高等) – KitsuneYMG 2010-02-03 06:25:57

+0

好散列映射的預期成本爲O(1),它不是保證是如此。不好的hashmaps可能有一個不是O(1)的預期成本。 – Clearer 2014-10-05 21:48:46

12

一些關鍵的區別在於複雜性要求。

映射需要O(log(N))時間來插入和查找。

unordered_map需要O(1)的「平均」時間用於插入和查找,但允許其最壞情況時間爲O(N)。

因此,通常unordered_map會更快,但取決於您存儲的密鑰和散列函數,可能會變得更糟。

0

我不知道給出了什麼,但是,hash_map需要超過20秒才能清除()150K無符號整數鍵和浮點值。我只是在跑步和閱讀別人的代碼。

這是它如何包含hash_map。

#include "StdAfx.h" 
#include <hash_map> 

我讀這這裏 https://bytes.com/topic/c/answers/570079-perfomance-clear-vs-swap

說清楚()是O(N)的順序。對我來說,這很奇怪,但是,事情就是這樣。