Wie man ein Array von einer PHP-Erweiterung zurückgibt, ohne es in den Speicher zu kopieren?

8

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?

    
Andrey Tserkus 24.07.2013, 20:39
quelle

3 Antworten

7

Wenn Ihre Funktion als Wert zurückgibt, ist dies erst ab PHP 5.6 (aktueller Master) mit dem Makro RETURN_ZVAL_FAST möglich:

%Vor%

Wenn Ihre Funktion by-reference ( return_reference=1 im arginfo) zurückgibt, können Sie den folgenden Code verwenden:

%Vor%

Wenn Ihre Funktion als Wert zurückgibt und Sie PHP 5.5 oder älter sind, können Sie den refcount=1 case:

noch optimieren %Vor%     
NikiC 01.08.2013 11:05
quelle
0

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.

    
jgmjgm 26.10.2015 17:09
quelle
-1

Es ist eine Weile her, seit ich so etwas programmiert habe ...

Also, was ich im Code unten mache: 1). explizit erhöhender Refcounter 2). Zurückgeben von Zval, ohne es zu kopieren

%Vor%     
JimiDini 24.07.2013 21:05
quelle

Tags und Links