2015-09-17 35 views
5

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?

+0

Wie viele Bytes reden wir? lol –

+0

@AdamBuchananSmith Bytes von was? –

+0

Umm ... von Speicher. –

Antwort

6

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_stringnicht 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.

+0

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. –

+1

@ 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

+0

Hm, hast du einen Link, um diesen Trick zu erklären? Hört sich interessant an. –