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什麼字節? –
嗯...記憶。 –