Hey, dort. Heute habe ich ein kleines Benchmark-Skript geschrieben, um die Leistung des Kopierens von Variablen mit dem Erstellen von Referenzen zu vergleichen. Ich hatte erwartet, dass das Erstellen von Verweisen auf große Arrays beispielsweise wesentlich langsamer wäre als das Kopieren des gesamten Arrays. Hier ist mein Benchmark-Code:
%Vor%Das eigentliche Ergebnis war, dass recursiveReference ungefähr 20 mal (!) so lange wie recursiveCopy dauerte.
Kann jemand dieses PHP-Verhalten erklären?
PHP wird sehr wahrscheinlich copy-on-write für seine Arrays implementieren, was bedeutet, dass Sie "kopieren" "Ein Array, PHP erledigt nicht die ganze Arbeit des physischen Kopierens des Speichers, bis Sie eine der Kopien geändert haben und Ihre Variablen nicht mehr auf dieselbe interne Repräsentation verweisen können.
Ihr Benchmarking ist daher grundlegend fehlerhaft, da Ihre recursiveCopy
-Funktion das Objekt nicht wirklich kopiert; Wenn dies der Fall wäre, würde Ihnen der Speicher schnell ausgehen.
Versuchen Sie Folgendes: Indem Sie einem Element des Arrays zuweisen, zwingen Sie PHP dazu, tatsächlich eine Kopie zu erstellen. Sie werden feststellen, dass Ihnen der Speicher schnell ausgeht, da keine der Kopien den Gültigkeitsbereich verlässt (und keine Daten gesammelt werden), bis die rekursive Funktion ihre maximale Tiefe erreicht hat.
%Vor%in recursiveReference Sie rufen recursiveCopy auf ... das macht keinen Sinn, in diesem Fall rufen Sie recursiveReference nur einmal auf. Korrigieren Sie Ihren Code, runden Sie den Benchmark erneut ab und kommen Sie mit Ihren neuen Ergebnissen zurück.
Außerdem denke ich nicht, dass es für einen Benchmark sinnvoll ist, dies rekursiv zu tun. Eine bessere Lösung wäre, eine Funktion 1000 Mal in einer Schleife aufzurufen - einmal mit dem Array direkt und einmal mit einem Verweis auf dieses Array.
Sie müssen Variablen nicht nur aus Performance-Gründen per Referenz zuweisen oder übergeben. PHP führt solche Optimierungen automatisch durch.
Der Test, den Sie ausgeführt haben, ist aufgrund dieser automatischen Optimierungen fehlerhaft. In dem folgenden Test wurde stattdessen ausgeführt:
%Vor%Dies war die Ausgabe:
%Vor%Wie Sie sehen können, gibt es keinen signifikanten Leistungsunterschied bei der Zuweisung durch Referenz, bis Sie tatsächlich in die Kopie schreiben, d. h. wenn es auch einen funktionalen Unterschied gibt.
Im Allgemeinen ist das Anrufen per Referenz in PHP nicht aus Leistungsgründen möglich. Es ist etwas, das Sie aus funktionalen Gründen tun würden - dh, weil Sie eigentlich möchten, dass die referenzierte Variable aktualisiert wird.
Wenn Sie keinen funktionalen Grund haben, per Referenz aufzurufen, sollten Sie bei der regulären Parameterübergabe bleiben, da PHP die Dinge auf diese Weise sehr effizient behandelt.
(das heißt, wie andere bereits gesagt haben, tut Ihr Beispielcode nicht genau das, was Sie sowieso denken;))
recursiveReference ruft recursiveCopy auf. Nicht, dass das der Performance schaden würde, aber das ist wahrscheinlich nicht das, was du versuchst zu tun.
Nicht sicher, warum die Leistung langsamer ist, aber es spiegelt nicht die Messung wieder, die Sie versuchen zu machen.
Tags und Links php benchmarking reference php-internals