2017-08-29 41 views
-1

我有一個非常性能密集的應用程序,我真的想避免製作一個保存在unordered_map中的字符串的副本。我希望能夠做的一個例子是將該字符串與本地字符串變量進行比較。是否可以訪問unordered_map中的元素而不復制它的副本?

例如,

unordered_map<string,string> X; 
string test = "def"; 
X["abc"] = test; 

//other operations here... 

string* map_entry = X.???; //some operation that doesn't make a copy of the string 

size_t map_entry_size = (*map_entry).size(); 

for (size_t i = 0; i < map_entry_size; ++i) 
{ 
if ((*map_entry)[i] != test[i]) 
    throw 1; 
} 

這是可能的,或者必須我一直在使用它之前使元素的副本?

+10

不清楚爲什麼你認爲你需要複製。 'operator []'返回一個引用,而不是一個副本... – user463035818

+5

取消引用迭代器返回一個引用,所以你沒有複製那裏。 – Jarod42

+3

無關:如果你曾經需要避免複製使用參考而不是指向安全的指針,你一些不必要的頭痛 – user463035818

回答

3

[]運算符將返回一個引用或const引用,所以沒有在那裏複製。迭代器會給你一個std::pair<std::string, std::string>的引用,所以再次沒有複製。

std::string &map_entry = X["abc"]; // Reference to value, no copy 
std::string *map_entry = &X["abc"]; // If you need a pointer 

如果你真的需要一個指針,做&map["key"]&iterator->second是有效的。

如果您在尋找性能,但是避免或至少小心使用std::string作爲一個關鍵是一個更加顯着的增益,尤其是如果鍵不是很短。

當然不認爲僅僅因爲一個無序的地圖是O(1)一個std::unordered_map<std::string, T>幾乎一樣快,用說的整數鍵,並且其進一步從密集的整數鍵,可能僅僅是一個正常的陣列中去除(即使兩者也將是O(1))。

  • 您需要臨時創建一個std::string。最壞的情況是這是一個動態的內存分配。對於小字符串,您使用的標準庫實現可能會有「小字符串優化」,但這仍然是一個副本。

    如果可能,您希望使用您已經從某個地方製作的現有std::string

  • 您需要計算散列(默認使用std::hash)和字符串長度爲O(n)的字符串。

    std::string沒有辦法來緩存它的散列,所以重用(例如一個常量/靜態)std::string不能避免這種情況,儘管你可以讓你自己的字符串包裝器。

  • 因爲散列可能發生衝突,如果unordered_map沒有找到一個條目,它則需要以防萬一,再次O(n)是字符串的長度(所以實際上沒有找到任何東西比快反正做一個完整的字符串比較找到正確的東西)。

使用說一個整數或其他小型固定大小的密鑰(也考慮,如果你知道你的弦總是小於說,4首或8個字節,你可以讓以「零填充」的整數),使散列是一個簡單的數學運算,並且比較單個運算。

使用密集整數(比如一個枚舉形式0到16)可以讓你使用一個數組,並且數組索引非常快。

相關問題