2016-01-06 69 views
7

在開始之前,我需要說明我的應用程序使用了很多字符串,這些字符串平均很小,並且一旦創建就不會改變。我可以讓std :: string使用更少的內存嗎?

在Visual Studio 2010中,我注意到std :: string的容量至少爲30.即使我寫入std::string str = "test";,str的容量也是30.函數str.shrink_to_fit()對此沒有任何幫助,雖然函數具有相同的功能名稱存在爲std :: vector並按預期工作,即降低容量以使容量==大小。

  1. 爲什麼std::string::shrink_to_fit()不能按預期工作?
  2. 如何確保字符串分配最少的內存?
+0

相關:http://stackoverflow.com/questions/2916358/immutable-strings-vs-stdstring – JimmyB

+0

你可以使用'std :: basic_string'自定義分配器。但是,這樣做會創建一個與'std :: string'不兼容的字符串類型。 – kfx

+0

這聽起來像是一個較小的緩衝區的小緩衝區優化。如果是小緩衝區優化,那麼你不能使它更小。 –

回答

8
  1. std::string實現最有可能使用某種形式的short string optimization的產生一個固定大小的小串和shrink_to_fit沒有影響。請注意,shrink_to_fit對於實現沒有約束力,所以這實際上是一致的。
  2. 您可以使用vector<char>來獲得更精確的內存管理,但會丟失std::string的一些附加功能。您也可以編寫自己的string包裝,它在內部使用vector
1

原因之一std::string::shrink_to_fit()什麼也不是,它不是由標準

備註要求:shrink_to_fit是一個不具約束力的要求,以減少對capacity()size()。 [注意:該請求不具有約束力,允許實現特定優化的緯度。末端注]

如果你想確保字符串收縮,那麼你可以使用swap()伎倆像

std::string(string_to_shrink).swap(string_to_shrink) 

另一個原因,這可能不起作用是,std::string實施者被允許執行short string optimization,因此您的實施始終可以有最小30的尺寸。

+0

交換技巧本質上是'shrink_to_fit'打算取代的。我認爲這裏的問題是SSO。 – pmr

1

您觀察到的是SSO(短字符串優化)的結果,正如其他人指出的那樣。

你能做些什麼取決於使用模式:

  • 如果字符串是一個大的字符串,這是典型的解析的部分,你可以使用類,如std::experimental::string_view,GSL string_span,谷歌的StringPiece,LLVM的StringRef等,它們本身不存儲數據,但只提供一些其他字符串,同時提供類似於std::string的接口。

  • 如果有多個相同字符串(特別是長字符串)的副本,那麼使用CoW(寫時複製)字符串是有意義的,其中副本使用引用計數器機制共享相同的緩衝區,直到修改。 (但要注意缺點的)

  • 如果字符串很短(只有幾個字符),它可能是有意義的編寫自己的專業門類,一些符合Handling short codes由安傑

不管您選擇的案例,建立良好的基準程序以清楚瞭解您獲得的效果(如果有)會很重要。

更新:重讀這個問題的介紹後,我認爲第三種方法是最適合你的。

相關問題