我試圖通過將字符串爲unordered_set<string>
,然後繞過shared_ptr<string>
的以削減字符串複製(已測得爲我的應用程序中的性能瓶頸)。很難知道集合中所有對字符串的引用何時被刪除,所以我希望shared_ptr可以幫助我。這是未經測試的代碼,說明我是多麼希望能夠把它寫:使用一個shared_ptr <string>到unordered_set <string>
unordered_set<string> string_pool;
:
shared_ptr<string> a = &(*string_pool.emplace("foo").first); // .first is an iterator
:
shared_ptr<string> b = &(*string_pool.emplace("foo").first);
在字符串「foo」應在string_pool上面,只有一個實例; a和b都應該指向它;並且在a和b都被破壞的時候,應該從string_pool中刪除「foo」。
暗示,但是對我來說並不明顯,那個指針a
可以在指針b
的分配引起的重新散亂中生存下來。它也似乎保證了「foo」的第二次放置不會導致任何重新分配,因爲它被認爲已經存在於集合中。
我在正確的軌道上嗎?我需要保持string_pool不斷增長,但是我沒有任何一點可以簡單地清除它,也沒有任何明確的字符串「擁有者」。
更新1
這個問題的歷史:這是一個「交通警察」的應用程序,從服務器,包裹出的數據讀入到其他服務器,接受他們的答案,包裹那些給他人,接收,最後彙編並返回一個簡要答案。它包括一個應用協議棧,它接收TCP消息,將它們解析爲字符串標量值,然後應用程序將其組裝成其他TCP消息,發送,接收等。我最初使用string
s,vectors<string>
s和字符串引用來編寫它,並且valgrind報告了「高數量」的字符串構造函數(即使使用-O3進行編譯),以及與字符串相關的庫例程中重點關注的高CPU使用率。我被要求調查減少字符串複製的方法,並設計了一個「memref」類(char *和指向輸入緩衝區的長度),可以複製這些類型來代替字符串本身。然後出現這種情況,需要重新使用輸入緩衝區,而memrefs仍然需要有效,所以我付了代價將每個緩衝區的子字符串複製到一個內部區域(unordered_set<string>
)中,並將memref指向那裏。然後我發現在這個過程中找到一個地方是很困難和不方便的,因爲在這個過程中,可以一次清理拘留區域(爲了防止它不受限制地增長),我開始嘗試重新設計拘留區域,以便當所有的遊覽區域interned字符串不見了,字符串將從池中刪除。因此shared_ptr。
正如我在@Peter R的評論中提到的那樣,我對移動語義和容器以及引用的瞭解比現在更不自在,而且很可能我沒有編寫簡單的,基於字符串的解決方案來使用所有C++ 11都可以提供。到現在爲止,我似乎一直在大循環旅行。
較大規模的ç unordered_set永遠不會超出範圍。我想它的主要貢獻是隻保留每個字符串值的單個實例。然而,更重要的是,當我最初編寫我一直試圖優化的代碼時,我比現在更瞭解移動語義和引用,而且我懷疑我寫的代碼效率低下。我會向OQ追加一個更好的解釋,我想要做什麼。 – Chap
稱爲「塊」的對象具有輸入緩衝區,其中讀取了製表符分隔的字符串。 Block的緩衝區解析器創建一個'std :: strings'的vector。用戶調用Block訪問器方法來獲取這些字符串。一旦它們在用戶的手中,它們的生命週期是不可預知的,並且它們肯定會超過輸入緩衝區和字符串向量。你是否同意這樣的字符串沒有「自然的所有者」? – Chap