PHP hat eine interne Datenstruktur namens smart string (smart_str?), In der sowohl die Länge als auch die Puffergröße gespeichert sind. Das heißt, mehr Speicher als die Länge der Zeichenfolge wird zugewiesen, um die Verkettungsleistung zu verbessern. Warum wird diese Datenstruktur nicht für die eigentlichen PHP-Strings verwendet? Würde das nicht zu weniger Speicherzuweisungen und besserer Leistung führen?Warum verwendet PHP keine interne Smart-Zeichenkette für Zeichenketten?
Antwort
Normale PHP-Strings (ab PHP 7) werden vom Typ zend_string
dargestellt, der sowohl die Länge der Zeichenfolge als auch deren Zeichendatenarray enthält. zend_string
s werden normalerweise zugewiesen, um die Zeichendaten genau anzupassen (Ausrichtung ungeachtet): Sie lassen keinen Platz zum Anhängen zusätzlicher Zeichen. Die smart_str
Struktur enthält einen Zeiger auf eine zend_string
und eine Zuweisungsgröße. Diesmal wird der zend_string
nicht genau zugeteilt. Stattdessen wird die Zuordnung zu groß gemacht, so dass zusätzliche Zeichen ohne teure Neuzuweisungen angehängt werden können.
Die Neuzuweisungsrichtlinie für smart_str
lautet wie folgt: Zuerst wird es zugewiesen, um eine Gesamtgröße von 256 Byte zu haben (abzüglich der Zend_string-Header, minus Allokator Overhead). Wenn diese Größe überschritten wird, wird sie auf 4096 Bytes neu zugewiesen (minus Overhead). Danach wird die Größe in Schritten von 4096 Bytes erhöht.
Stellen Sie sich nun vor, dass wir alle Zeichenfolgen durch smart_str
ersetzen. Dies würde bedeuten, dass selbst eine einzelne Zeichenfolge eine Mindestzuweisungsgröße von 256 Byte hätte. Angesichts der Tatsache, dass die meisten verwendeten Strings klein sind, ist dies ein inakzeptabler Overhead.
Also im Wesentlichen ist dies eine klassische Performance/Speicher-Kompromiss. Wir verwenden standardmäßig eine speicherkompakte Darstellung und wechseln zu einer schnelleren, aber weniger speichereffektiven Darstellung in den Fällen, die am meisten davon profitieren, d. H. Wenn große Zeichenfolgen aus kleinen Teilen bestehen.
Sicher, aber Sie könnten immer noch den 'smart_str' optimieren, um besser auf die normale PHP-String-Handhabung zu reagieren, oder? Beginnen Sie mit kleiner Größe und verdoppeln Sie es dann jedes Mal, wenn die Verkettung stattfindet. Zumal String-Puffer in PHP (!) Nicht implementiert werden können. Und vor allem, weil Speicher mehr als CPU-Zyklen vorhanden ist. –
@ OlleHärstedt Ja, es ist wahrscheinlich möglich, eine vernünftige Zuteilungspolitik zu finden, sobald Sie beginnen, die Kapazität überhaupt zu speichern. Ich habe speziell hier über smart_str geantwortet. Eine relativ sichere Sache ist es, mit dem Allokator zu integrieren und (für kleine Allokationen) die nächstgrößere Bucket-Größe auszuwählen, die sowieso verwendet wird. Mit ein wenig Tricks wäre es sogar möglich, keinen zusätzlichen Speicheraufwand für das Speichern der Kapazität einzuführen (mit Pseudo-Float-Encoding). Das macht HHVM;) – NikiC
Hm, hast du einen Link, um diesen Trick zu erklären? Hört sich interessant an. –
- 1. Erstellt .NET einen Pool für interne Zeichenketten für jede Assembly?
- 2. Interne Darstellung von Zeichenketten in C#
- 3. PHP - Variable interne Variable?
- 4. Warum kann meine öffentliche Klasse keine interne Klasse erweitern?
- 5. Mehrere Zeichenketten für Lokalisierung exportieren
- 6. PHP enthalten/erfordern interne Funktionen
- 7. Interne Fehlermeldung für AWSDataPipeline
- 8. Wie verwendet die JVM interne String-Teilstrings?
- 9. Warum verwendet Go HTTPS Client keine Verbindungen?
- 10. Warum werden keine Erlang-Pakete verwendet?
- 11. Warum verwendet das Wordpress-Datenbankschema keine Fremdschlüssel?
- 12. PHP: Warum gibt exec() keine Ausgabe zurück?
- 13. Warum funktioniert Browsermobproxy nicht für meine interne IP?
- 14. Richtlinien für interne Klassenmembergruppierung
- 15. ADFS-Implementierung für interne Anwendungen
- 16. Ruby: Warum ändern sich Symbole in Zeichenketten, wenn Puts anstelle von Drucken verwendet wird?
- 17. Ignorieren öffentliche/interne Felder für NHibernate-Proxy
- 18. Interne Darstellung von Strings in PHP
- 19. Warum php mail() - Funktion erfordert keine Authentifizierung?
- 20. Extract Dateiname mit Verzeichnisstruktur für interne Website
- 21. Warum gibt es keine interne Controller-Umleitung in ASP.Net MVC (oder CodeIgniter)?
- 22. Interne Datei für Login speichern
- 23. Warum hat ServiceStack.Text keine Daten für iso8601?
- 24. AndroidTest verwendet keine Testanwendung
- 25. Die eleganteste Art, Zeichenketten in Zeichenketten umzuwandeln
- 26. Warum verwendet Scalaz komplexe Symbole und keine In-Code-Dokumentation?
- 27. Wie verwendet man Zeichenketten als Daten zum Zeichnen in Matlab?
- 28. mod_rewrite für saubere URLs gibt 500 interne Server Fehler
- 29. Warum definiert C# keine Additionsoperation für Chars?
- 30. Interne Klassen für andere sichtbar machen Assemblies
Wie viele Bytes reden wir? lol –
@AdamBuchananSmith Bytes von was? –
Umm ... von Speicher. –