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. –
Wie viele Bytes reden wir? lol –
@AdamBuchananSmith Bytes von was? –
Umm ... von Speicher. –