簡體   English   中英

c++中map和unordered_map的性能差異

[英]Difference in performance between map and unordered_map in c++

我有一個簡單的要求,我需要一個類型的地圖。 但是我需要最快的理論上可能的檢索時間。

我同時使用了 map 和 tr1 中新提出的 unordered_map 我發現至少在解析文件和創建映射時,通過在時間插入一個元素。

map 只用了 2 分鍾,而 unordered_map 用了 5 分鍾。

由於它將成為要在 Hadoop 集群上執行的代碼的一部分,並且將包含約 1 億個條目,因此我需要盡可能短的檢索時間。

還有另一個有用的信息:目前正在插入的數據(鍵)是從 1,2,... 到 ~1000 萬的整數范圍。

我還可以強制用戶指定最大值並使用上述順序,這會顯着影響我的實現嗎? (我聽說地圖基於 rb 樹,並且按遞增順序插入會導致更好的性能(或最差?))

這是代碼

map<int,int> Label // this is being changed to unordered_map  
fstream LabelFile("Labels.txt");  


// Creating the map from the Label.txt  
if (LabelFile.is_open())  
{  
    while (! LabelFile.eof() )  
    {             
        getline (LabelFile,inputLine);  
        try  
        {  
            curnode=inputLine.substr(0,inputLine.find_first_of("\t"));  
            nodelabel=inputLine.substr(inputLine.find_first_of("\t")+1,inputLine.size()-1);  
            Label[atoi(curnode.c_str())]=atoi(nodelabel.c_str());  
        }  
        catch(char* strerr)  
        {  
            failed=true;  
            break;  
        }  
    }  
    LabelFile.close(); 
}

暫定解決方案:在查看評論和答案后,我相信動態 C++ 數組將是最佳選擇,因為實現將使用密集鍵。 謝謝

unordered_map 的插入應該是O(1)並且檢索應該大約是O(1) ,(它本質上是一個哈希表)。

您的時間,結果是方式關閉,或者有什么不對您的實現或unordered_map的使用。

您需要提供更多信息,以及您可能如何使用容器。

根據 n1836 的第 6.3 節,給出了插入/檢索的復雜性:

您應該考慮的一個問題是您的實現可能需要不斷地重新調整結構,正如您所說的您有100mil+ items 在這種情況下,在實例化容器時,如果您對將有多少“唯一”元素插入容器有一個粗略的想法,您可以將其作為參數傳遞給構造函數,容器將相應地使用一個桶進行實例化 -大小合適的桌子。

加載 unordered_map 的額外時間是由於動態數組大小調整所致。 調整大小計划是在表格超過其加載因子時將每個單元格的數量加倍。 因此,從一個空表中,期望整個數據表的 O(lg n) 個副本。 您可以通過預先調整哈希表的大小來消除這些額外的副本。 具體來說

Label.reserve(expected_number_of_entries / Label.max_load_factor());

除以 max_load_factor 是為了說明哈希表運行所必需的空單元格。

unordered_map(至少在大多數實現中)提供快速檢索,但與 map 相比插入速度相對較差。 當數據隨機排序時,樹通常處於最佳狀態,而在數據有序時則處於最差狀態(您不斷地在樹的一端插入,增加重新平衡的頻率)。

鑒於它總共有大約 1000 萬個條目,您可以分配一個足夠大的數組,並獲得非常快速的查找——假設有足夠的物理內存不會導致抖動,但按照現代標准,這並不是大量的內存。

編輯:是的,向量基本上是一個動態數組。

Edit2:您添加了一些問題的代碼。 你的while (! LabelFile.eof() )壞了。 你通常想要做一些類似while (LabelFile >> inputdata)事情。 您還有些低效地讀取數據——您顯然期望的是由制表符分隔的兩個數字。 既然如此,我會寫這樣的循環:

while (LabelFile >> node >> label)
    Label[node] = label;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM