为啥 PHP 不对字符串使用内部智能字符串?
Posted
技术标签:
【中文标题】为啥 PHP 不对字符串使用内部智能字符串?【英文标题】: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_
* 函数处理。因此,使所有字符串“智能”是微不足道的。我想这是一个深思熟虑的决定,那就是不“聪明”。
【参考方案1】:
普通的 PHP 字符串(自 PHP 7 起)由 zend_string
类型表示,它包括字符串的长度及其字符数据数组。 zend_string
s 通常被分配以精确匹配字符数据(尽管对齐):它们不会留下位置来附加额外的字符。
smart_str
结构包括一个指向zend_string
的指针和一个分配大小。这一次,zend_string
将不会被精确分配。相反,分配将变得太大,因此可以附加额外的字符而无需进行昂贵的重新分配。
smart_str
的重新分配策略如下:首先,将分配总大小为 256 字节(减去 zend_string 标头,减去分配器开销)。如果超过这个大小,它将被重新分配到 4096 字节(减去开销)。之后,大小将以 4096 字节为增量增加。
现在,假设我们用smart_str
ings 替换所有字符串。这意味着即使是单个字符串也将具有 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/…以上是关于为啥 PHP 不对字符串使用内部智能字符串?的主要内容,如果未能解决你的问题,请参考以下文章
javascript,innerHTML或者innerText获取的内容是否字符串?为啥和另外一个字符串相比结果不对