PHP有一个称为智能字符串(smart_str?)的内部数据结构,它们存储长度和缓冲区大小。也就是说,分配的内存超过了字符串的长度以提高串联性能。为什么这个数据结构不是用于实际的PHP字符串?这不会导致更少的内存分配和更好的性能吗?为什么PHP不使用内部智能字符串作为字符串?
回答
正常PHP字符串(从PHP 7开始)由zend_string
类型表示,其中包括字符串的长度和其字符数据数组。通常会分配zend_string
以精确地匹配字符数据(尽管对齐):他们不会留下附加字符的位置。
smart_str
结构包括指向zend_string
的指针和分配大小。这一次,zend_string
将而不是被精确分配。相反,分配将会变得太大,这样可以附加额外的字符而不需要昂贵的重新分配。
smart_str
的重新分配策略如下:首先,它将被分配为总大小为256个字节(减去zend_string头,减去分配器开销)。如果超过这个大小,它将被重新分配到4096字节(减去开销)。之后,大小将以4096字节为增量增加。
现在,想象一下,我们用smart_str
来取代所有的字符串。这意味着即使是单个字符串也会有256字节的最小分配大小。鉴于大多数使用的字符串都很小,这是不可接受的开销。
所以基本上,这是一个经典的性能/内存折衷。默认情况下,我们使用内存压缩表示,并且在从中受益最多的情况下切换到更快但更少的内存有效表示,即从小部分构建大型字符串的情况。
当然,但您仍然可以调整'smart_str'以更好地适应正常PHP字符串处理的需要,对吗?通过从小尺寸开始,然后每次连接发生时加倍。特别是因为字符串缓冲区不可能在PHP(!)中实现。尤其是因为内存比CPU周期更丰富。 –
@OlleHärstedt是的,一旦开始存储容量,很可能会找到一些合理的分配策略。我在这里专门回答smart_str。一个相对安全的做法是与分配器集成,并且(对于小分配)选择将要使用的下一个最大桶大小。有一些诡计,甚至有可能不引入额外的内存开销来存储容量(使用伪浮点编码)。这就是HHVM所做的;) – NikiC
嗯,你有链接来解释这个骗局吗?听起来不错。 –
- 1. 为什么我们不能使用C字符串作为SEL?
- 2. 为什么不使用CONCAT()作为静态字符串文字?
- 3. 为什么隔离的作用域(=)不能使用字符串?
- 4. '@'作为内部剃刀字符串不工作的字符
- 5. 为什么我不能擦除字符串的数字字符?
- 6. 在字符串中使用PHP作为字符串。 (jQuery)
- 7. JQuery.each将字符串文字转换为字符串。为什么?
- 8. 为什么我不能在awk中使用字符串“?B?”作为分隔符
- 9. 为什么非字母字符串不能包含换行符?
- 10. PHP字符串中的智能字符串中断
- 11. 为什么不能将符号值转换为字符串
- 12. 反向字符串(Leetcode)使用C++,为什么我不能返回新字符串作为方法
- 13. 为什么NULL字符串与“”字符串不同?
- 14. 为什么id(字符串)不返回字符串的地址
- 15. 字符串数组加字符串不是错误,为什么?
- 16. C#:为什么字符串不能用字符串文字作为参数来构造?
- 17. 为什么字符串被称为“字符串”?
- 18. 字面操作符模板:为什么不是字符串?
- 19. 为什么我的字符串不能用作URL?
- 20. 为什么不能用我的字符串输入工作?
- 21. 为什么不能将字符串用作Docstrings?
- 22. 为什么在调用字符串中的字符时不能替换工作?
- 23. C# - 为什么我不能在字符串内使用三元操作?
- 24. 为什么使用文字字符构建Clojure字符串?
- 25. GSON反序列化字符串[]为一个字符串内部的字符串
- 26. 为什么我不能用美元符号分割字符串?
- 27. 为什么在循环内部不重置字符串?
- 28. 为什么内部静态字符串是不可访问,类
- 29. 使用字符串作为分隔符来拆分字符串
- 30. 为什么不打印此功能顶部的字符串?
我们在谈论多少个字节?大声笑 –
@AdamBuchananSmith什么字节? –
嗯...记忆。 –