【问题标题】:Why doesn't PHP use internal smart string for strings?为什么 PHP 不对字符串使用内部智能字符串?
【发布时间】:2015-12-14 21:26:53
【问题描述】:

PHP 有一个称为智能字符串 (smart_str?) 的内部数据结构,它们在其中存储长度和缓冲区大小。也就是说,分配比字符串长度更多的内存来提高连接性能。为什么这个数据结构不用于实际的 PHP 字符串?这不会导致更少的内存分配和更好的性能吗?

【问题讨论】:

  • 我们说的是多少字节?大声笑
  • @AdamBuchananSmith 什么字节?
  • 在 PHP 7 中,所有字符串都是zend_string 类型,分配和释放由zend_string_* 函数处理。因此,使所有字符串“智能”是微不足道的。我想这是一个深思熟虑的决定,那就是不“聪明”。

标签: string php-internals


【解决方案1】:

普通的 PHP 字符串(自 PHP 7 起)由 zend_string 类型表示,它包括字符串的长度及其字符数据数组。 zend_strings 通常被分配以精确匹配字符数据(尽管对齐):它们不会留下位置来附加额外的字符。

smart_str 结构包括一个指向zend_string 的指针和一个分配大小。这一次,zend_string 将不会被精确分配。相反,分配将变得太大,因此可以附加额外的字符而无需进行昂贵的重新分配。

smart_str 的重新分配策略如下:首先,将分配总大小为 256 字节(减去 zend_string 标头,减去分配器开销)。如果超过这个大小,它将被重新分配到 4096 字节(减去开销)。之后,大小将以 4096 字节为增量增加。

现在,假设我们用smart_strings 替换所有字符串。这意味着即使是单个字符串也将具有 256 字节的最小分配大小。鉴于使用的大多数字符串都很小,这是不可接受的开销。

所以本质上,这是一个经典的性能/内存权衡。我们默认使用内存紧凑的表示,并在从中受益最多的情况下切换到更快但内存效率较低的表示,即大字符串由小部分构成的情况。

【讨论】:

  • 当然可以,但是您仍然可以调整smart_str 以更好地满足普通 PHP 字符串处理的需要,对吧?从小尺寸开始,然后在每次连接发生时加倍。特别是因为字符串缓冲区不可能在 PHP 中实现(!)。尤其是因为内存比 CPU 周期更丰富。
  • @OlleHärstedt 是的,一旦开始存储容量,就有可能找到一些合理的分配策略。我在这里专门回答了 smart_str 。一种相对安全的做法是与分配器集成,并且(对于小型分配器)选择无论如何都会使用的下一个最大存储桶大小。通过一些技巧,甚至可以不引入额外的内存开销来存储容量(使用伪浮点编码)。这就是 HHVM 所做的 ;)
  • 嗯,你有解释这个诡计的链接吗?听起来很有趣。
  • @OlleHärstedt 当然,这里是 cap 代码实现:lxr.php.net/xref/OTHER_IMPLEMENT/hiphop-vm/hphp/runtime/base/… PHP 没有额外内存开销的原因是我们可以安全地将哈希缓存缩小到 32 位,留下 32 位用于编码容量值。这是用于选择字符串容量的 HHVM 实现:lxr.php.net/xref/OTHER_IMPLEMENT/hiphop-vm/hphp/runtime/base/…
猜你喜欢
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-30
  • 2013-05-18
相关资源
最近更新 更多