簡體   English   中英

使用std :: map和std :: string鍵與int鍵的成本?

[英]Cost of using std::map with std::string keys vs int keys?

我知道單個地圖查詢最多占用log(N)時間。 但是我想知道,我已經看到很多使用字符串作為映射鍵的示例。 例如,將std :: string作為鍵與地圖而不是int相關聯的性能成本是多少?

std::map<std::string, aClass*> someMap; vs std::map<int, aClass*> someMap;

謝謝!

分析漸近性能的算法正在研究必須執行的操作以及它們添加到等式中的成本。 為此,您需要首先了解執行的操作是什么,然后評估其成本。

在平衡二叉樹中搜索密鑰(映射恰好是)需要O( log N )復雜操作。 這些操作中的每一個都意味着比較匹配的密鑰並且如果密鑰不匹配則遵循適當的指針(子)。 這意味着總成本與log N乘以這兩個操作的成本成比例。 以下指針是一個恆定時間操作O(1) ,比較鍵取決於鍵。 對於整數鍵,比較快速為O(1) 比較兩個字符串是另一個故事,它需要時間與所涉及的字符串的大小成比例O(L) (其中我故意使用L作為字符串參數的長度而不是更常見的N

當您將所有成本加起來時,您可以使用整數作為關鍵字,總成本為O( log N )*( O(1) + O(1) ) ,相當於O( log N ) O(1)隱藏在O符號默默隱藏的常量中。

如果使用字符串作為鍵,則總成本為O( log N )*( O(L) + O(1) ) ,其中常量時間操作被更昂貴的線性操作O(L)隱藏,並且可以轉換為O( L * log N ) 也就是說,在由字符串鍵入的映射中定位元素的成本與存儲在映射中的元素的數量的對數乘以用作鍵的字符串的平均長度成比例。

請注意,big-O表示法最適合用作分析工具來確定算法在問題規模增長時的行為方式,但它隱藏了許多對原始性能很重要的事實。

作為最簡單的示例,如果將密鑰從通用字符串更改為1000個字符的數組,則可以隱藏在符號中刪除的常量中的成本。 比較1000個字符的數組是一個常數操作,恰好需要相當長的時間。 漸近符號只是一個O( log N )操作,就像整數一樣。

許多其他隱藏成本也會發生同樣的情況,因為創建元素的成本通常被視為一個恆定時間操作,僅僅因為它不依賴於您的問題的參數(在每個成本中定位內存塊的成本)分配不依賴於您的數據集,而是依賴於算法分析范圍之外的內存碎片,獲取malloc內部鎖定的成本以保證不會有兩個進程嘗試返回相同的內存塊取決於鎖的爭用取決於處理器,進程的數量以及它們執行的內存請求的數量......,再次超出了算法分析的范圍)。 在閱讀大O符號的成本時,你必須意識到它的真正含義。

除了比較已經提到的字符串的時間復雜性之外,每次將項添加到容器時,字符串鍵還將導致額外的內存分配。 在某些情況下,例如高度並行的系統,全局分配器互斥體可能是性能問題的根源。

通常,您應該選擇在您的情況下最有意義的替代方案,並且僅基於實際性能測試進行優化。 眾所周知,很難判斷出什么是瓶頸。

成本差異將與比較兩個總體與比較兩個字符串之間的成本差異相關聯。

比較兩個字符串時,必須取消引用指向第一個字符的指針,然后比較它們。 如果它們相同,則必須比較第二個字符,依此類推。 如果你的字符串有一個很長的公共前綴,這可能會使這個過程變慢。 但是,它不太可能像比較一樣快。

成本是當然可以在實際O(1)時間內比較整數,而在O(n)時間(n是最大共享前綴)中比較字符串。 此外,字符串的存儲消耗比整數的空間更多的空間。 除了這些明顯的差異之外,沒有重大的性能成本。

簡單的例子是只使用相同數量的鍵訪問兩個映射中的值 - 一個int鍵使用相同的int值的另一個字符串需要8倍的字符串。

首先,我懷疑在實際的應用程序中,無論你是否有字符串鍵或int鍵都會產生明顯的差異。 分析您的應用程序將告訴您它是否重要。

如果它確實重要,您可以將密鑰更改為此類(未經測試):

class Key {
public:
    unsigned hash;
    std::string s;

    int cmp(const Key& other) {
        int diff = hash - other.hash;
        if (diff == 0)
            diff = strcmp(s, other.s);
        return diff;
}

現在你正在對兩個字符串的哈希進行int比較。 如果散列不同,則字符串肯定不同。 如果散列是相同的,你仍然需要比較字符串,因為Pigeonhole原則

暫無
暫無

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

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