在开始之前,我需要说明我的应用程序使用了很多字符串,这些字符串平均很小,并且一旦创建就不会改变。
在Visual Studio 2010中,我注意到std :: string的容量至少为30.即使我写std::string str = "test";
,str的容量也是30.函数str.shrink_to_fit()
什么都不做虽然std :: vector存在一个具有相同名称的函数,并且按预期工作,即减小容量以使容量== size。
std::string::shrink_to_fit()
无法正常工作?答案 0 :(得分:8)
std::string
实施最有可能使用short string optimization的某种形式,导致较小字符串的大小固定,shrink_to_fit
无效。请注意,shrink_to_fit
对于实现是非约束性的,因此这实际上符合要求。vector<char>
来获得更精确的内存管理,但会失去std::string
的一些附加功能。您也可以编写自己的string
包装器,内部使用vector
。答案 1 :(得分: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。
答案 2 :(得分:1)
您观察到的是SSO(短字符串优化)的结果,正如其他人所指出的那样。
您可以做些什么取决于使用模式:
如果字符串是一个大字符串的一部分(这是解析的典型字符串),则可以使用std::experimental::string_view
,GSL string_span
,Google的StringPiece,LLVM和#39等类。 ; s StringRef等,它们本身不存储数据,但只引用一些其他字符串,同时提供类似于std::string
的界面。
如果存在相同字符串的多个副本(尤其是长字符串),则使用CoW(写时复制)字符串可能是有意义的,其中副本使用引用计数器机制共享相同的缓冲区,直到修改为止。 (但要注意缺点)
如果字符串很短(只有几个字符),编写自己的专门课程可能是有意义的,这与Andrzej的Handling short codes一致
无论您选择何种情况,都必须建立良好的基准程序,以清楚地了解您获得的效果(如果有的话)。
更新:在重新阅读问题的介绍之后,我认为第三种方法对你来说是最好的。
答案 3 :(得分:0)
如果您在应用程序中使用了很多小字符串,那么您可能需要查看fbstring(https://github.com/facebook/folly/blob/master/folly/docs/FBString.md)。