5

我在我的代码中使用了所有 std::string 对象,其中大多数是堆栈分配的。我替换了默认的 new/delete 运算符来检查平均内存分配大小,我惊讶地发现大多数分配来自 std::string,这非常重要,它们在 12 到 32 字节之间!为了优化这一点(从免费存储中分配的大量小字符串),我提出了一个简单的解决方案:

  • 实现自定义字符串类
  • 在其中添加具有固定大小的预定义缓冲区,例如 64 字节(我可以在分析后调整此大小)
  • 当字符串的长度小于 64 字节时使用预定义的缓冲区,或者从空闲存储中为更大的字符串分配新的缓冲区。

通过这个实现,我将为长度大于 64 的所有字符串添加 64 字节的内存开销,并向短于 64 字节的字符串添加(64-lenth)开销,但我将阻止所有小字符串的分配。

你试过这样的方法吗?增加这种内存开销是否合理,大部分时间都在堆栈上以节省分配时间/内存碎片?

这种方法比自定义 str::string 分配器更好吗?

4

3 回答 3

7

合理吗?这取决于。std::string除非您通过使用或发现持续分配和解除分配的实际(与感知相反的)性能问题而发现自己实际上耗尽了内存,否则您就是在浪费时间这样做。

不要误会我的意思,您可以(而且我已经)通过使用标准分配器无法获得的额外信息获得了巨大的收益。但是,除非有真正的问题需要解决,否则最好使用标准方法并将时间花在其他地方。

于 2012-12-21T09:29:00.587 回答
5

我认为它之前已经按照您提到的方式在愚蠢中做过:“fbstring 是 std::string 的替代品。fbstring 的主要好处是显着提高了几乎所有重要原语的性能。”

https://github.com/facebook/folly/blob/master/folly/docs/FBString.md

这应该得到很好的优化:

存储策略

小字符串(<= 23 个字符)原位存储,无需内存分配。

中等字符串(24 - 255 个字符)存储在 malloc 分配的内存中并急切地复制。

大字符串(> 255 个字符)存储在 malloc 分配的内存中并延迟复制。

于 2012-12-21T09:28:11.087 回答
2

你试过这样的方法吗?

不,但我确实编写了自己的分配器。这是我更喜欢的替代方案。

增加这种内存开销是否合理,大部分时间都在堆栈上以节省分配时间/内存碎片?

什么是“合理”的定义因您的情况而异。你需要防止内存碎片吗?您是否需要最小化分配数量?以每个字符串的额外内存为代价来最大化速度?

您只是想优化 std:: 实现作为练习吗?

您是否有具有性能(或内存)限制的目标平台?

这些问题中的每一个都会改变答案(关于内存开销是否合理)。

这种方法比自定义 str::string 分配器更好吗?

取决于你的情况。

于 2012-12-21T10:36:21.320 回答