我可以使std :: string使用更少的内存吗?

时间:2016-01-06 13:16:23

标签: c++ string visual-studio-2010 memory

在开始之前,我需要说明我的应用程序使用了很多字符串,这些字符串平均很小,并且一旦创建就不会改变。

在Visual Studio 2010中,我注意到std :: string的容量至少为30.即使我写std::string str = "test";,str的容量也是30.函数str.shrink_to_fit()什么都不做虽然std :: vector存在一个具有相同名称的函数,并且按预期工作,即减小容量以使容量== size。

  1. 为什么std::string::shrink_to_fit()无法正常工作?
  2. 如何确保字符串分配最少的内存?

4 个答案:

答案 0 :(得分:8)

  1. 您的std::string实施最有可能使用short string optimization的某种形式,导致较小字符串的大小固定,shrink_to_fit无效。请注意,shrink_to_fit对于实现是非约束性的,因此这实际上符合要求。
  2. 您可以使用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)。