Ich entwickle eine PHP-Erweiterung, bei der eine Objektmethode ein Array zval
zurückgeben muss.
Die Methode sieht folgendermaßen aus:
%Vor% Der Code funktioniert gut und macht die erwartete Sache - er gibt das myArrayProperty
des Objekts zurück. Ich möchte jedoch den Prozess optimieren.
myArrayProperty
speichert ein Array, das ziemlich groß sein kann. Und das Makro RETURN_ZVAL()
dupliziert dieses Array, um den Wert zurückzugeben. Der Duplizierungsprozess benötigt viel Zeit, um Speicher zu erhalten und alle Array-Werte zu kopieren. Zur gleichen Zeit wird das zurückgegebene Array normalerweise für schreibgeschützte Operationen verwendet. Eine schöne Optimierung wäre also, den Mechanismus von PHP mit Referenzzählung zu verwenden und myArrayProperty
Inhalte nicht zu duplizieren. Stattdessen würde ich refcount
von myArrayProperty
erhöhen und einfach den Zeiger darauf zurückgeben. Dies ist die gleiche Taktik wie beim Arbeiten mit Variablen in einer PHP-Erweiterung.
Wie es scheint, gibt es dazu keine Möglichkeit - Sie müssen den Wert duplizieren, um ihn von einer PHP-Erweiterungsfunktion zurückzugeben. Das Ändern der Funktionssignatur, um den Wert als Referenz zurückzugeben, ist keine Option, da sie die Eigenschaft und den zurückgegebenen Wert verbindet, d. H. Den zurückgegebenen Wert später ändert, ändert sich auch die Eigenschaft. Das ist kein akzeptables Verhalten.
Die Unfähigkeit, Referenzzählung einzuschalten, sieht seltsam aus, weil in PHP derselbe Code verwendet wird:
%Vor%wird durch den Referenzzählmechanismus optimiert. Deshalb stelle ich diese Frage bei StackOverflow, falls ich etwas verpasst habe.
Gibt es also eine Möglichkeit, ein Array von einer Funktion in der PHP-Erweiterung zurückzugeben, ohne das Array im Speicher zu kopieren?
Wenn Ihre Funktion als Wert zurückgibt, ist dies erst ab PHP 5.6 (aktueller Master) mit dem Makro RETURN_ZVAL_FAST
möglich:
Wenn Ihre Funktion by-reference ( return_reference=1
im arginfo) zurückgibt, können Sie den folgenden Code verwenden:
Wenn Ihre Funktion als Wert zurückgibt und Sie PHP 5.5 oder älter sind, können Sie den refcount=1
case:
Ich habe keinen Zugriff auf PHP & lt; 5.6 aber ich denke das Problem ist, dass der Wert nur kopiert wird. Um absolut sicher zu sein, sollten Sie den Code nach den entsprechenden Definitionen durchsuchen.
Das bedeutet, dass Sie möglicherweise versuchen können:
%Vor%Dies ist gefährlich, wenn es unbedacht verwendet wird. Bei Verwendung mit eigenen temporären Containern sind mir keine Probleme bekannt.
Sie können wahrscheinlich auch direkt am Rückgabewert arbeiten, was ein besserer Ansatz sein könnte. Sie würden es wahrscheinlich initialisieren und es als Zeiger am Anfang weitergeben.
Sie können Ihr Rückgabeergebnis wie folgt umbrechen. Sie können auch mit Referenzen experimentieren.
Tags und Links c php php-internals php-extension