Heim > Artikel > Backend-Entwicklung > Baidu-Ingenieure sprechen über die Implementierungsprinzipien und Leistungsanalyse von PHP-Funktionen (1)
Baidu-Ingenieure sprechen über die Implementierungsprinzipien und Leistungsanalyse von PHP-Funktionen (1)
Vorwort Referenzquelle:
In jeder Sprache sind Funktionen die grundlegendsten Bausteine. Was sind die Merkmale von PHP-Funktionen? Wie wird der Funktionsaufruf implementiert? Wie ist die Leistung von PHP-Funktionen? Gibt es Vorschläge zur Verwendung? In diesem Artikel werden die Prinzipien analysiert und mit tatsächlichen Leistungstests kombiniert, um zu versuchen, diese Fragen zu beantworten und PHP-Programme besser zu schreiben und gleichzeitig die Implementierung zu verstehen. Gleichzeitig werden einige gängige PHP-Funktionen vorgestellt.
Klassifizierung von PHP-Funktionen
In PHP werden Funktionen bei horizontaler Aufteilung in zwei Kategorien unterteilt: Benutzerfunktion (integrierte Funktion) und interne Funktion (integrierte Funktion). Ersteres sind einige Funktionen und Methoden, die vom Benutzer im Programm angepasst wurden, und letzteres sind verschiedene Bibliotheksfunktionen, die von PHP selbst bereitgestellt werden (z. B. Sprintf, Array_Push usw.). Benutzer können Bibliotheksfunktionen auch über Erweiterungsmethoden schreiben, die später vorgestellt werden. Die Benutzerfunktion kann in Funktion (Funktion) und Methode (Klassenmethode) unterteilt werden. In diesem Artikel werden diese drei Funktionen analysiert und getestet.
Implementierung der PHP-Funktion
Wie wird eine PHP-Funktion letztendlich ausgeführt? Wie sieht der Prozess aus?
Um diese Frage zu beantworten, werfen wir zunächst einen Blick auf den Prozess der Ausführung des PHP-Codes.
Wie Sie in Abbildung 1 sehen können, implementiert PHP einen typischen dynamischen Sprachausführungsprozess: Nach Erhalt eines Codeabschnitts, nach lexikalischer Analyse, Syntaxanalyse und anderen Phasen wird das Quellprogramm übersetzt a-Anweisungen (Opcodes), und dann führt die virtuelle ZEND-Maschine diese Anweisungen nacheinander aus, um den Vorgang abzuschließen. PHP selbst ist in C implementiert, daher sind die letztendlich aufgerufenen Funktionen alle C-Funktionen. Tatsächlich können wir PHP als eine in C entwickelte Software betrachten. Aus der obigen Beschreibung ist nicht schwer zu erkennen, dass die Ausführung von Funktionen in PHP auch in Opcodes zum Aufruf übersetzt wird. Jeder Funktionsaufruf führt tatsächlich eine oder mehrere Anweisungen aus.
Zend beschreibt jede Funktion durch die folgende Datenstruktur
wobei Typ den Typ der Funktion angibt: Benutzerfunktion, integrierte Funktion, überladene Funktion. Common enthält die grundlegenden Informationen der Funktion, einschließlich Funktionsname, Parameterinformationen, Funktionsflags (normale Funktionen, statische Methoden, abstrakte Methoden) usw. Darüber hinaus gibt es für Benutzerfunktionen auch eine Funktionssymboltabelle, in der interne Variablen usw. aufgezeichnet werden, die später ausführlich beschrieben werden. Zend verwaltet eine globale function_table, eine große Hash-Tabelle. Wenn eine Funktion aufgerufen wird, wird die entsprechende zend_function zunächst anhand des Funktionsnamens aus der Tabelle gefunden. Bei einem Funktionsaufruf bestimmt die virtuelle Maschine die aufrufende Methode anhand des Typs. Verschiedene Funktionstypen haben unterschiedliche Ausführungsprinzipien.
Eingebaute Funktionen
Eingebaute Funktionen sind im Wesentlichen echte C-Funktionen. Nach der endgültigen Kompilierung wird PHP in eine Funktion mit dem Namen zif_xxxx erweitert. Unser gemeinsamer Sprintf entspricht beispielsweise der untersten Ebene . zif_sprintf. Wenn Zend bei der Ausführung eine integrierte Funktion findet, führt es einfach eine Weiterleitungsoperation durch.
Zend bietet eine Reihe von APIs zum Aufrufen, einschließlich Parametererfassung, Array-Operationen, Speicherzuweisung usw. Die Parameter der integrierten Funktion werden über die Methode zend_parse_parameters abgerufen. Für Parameter wie Arrays und Zeichenfolgen implementiert Zend flaches Kopieren, sodass diese Effizienz sehr hoch ist. Man kann sagen, dass die Effizienz der in PHP integrierten Funktionen nahezu mit der der entsprechenden C-Funktionen übereinstimmt, mit dem einzigen zusätzlichen Weiterleitungsaufruf.
Eingebaute Funktionen werden in PHP dynamisch geladen, sodass Benutzer entsprechend ihren Anforderungen auch entsprechende schreiben können, was wir oft als Erweiterungen bezeichnen. ZEND bietet eine Reihe von APIs zur Erweiterung
Benutzerfunktionen
Im Vergleich zu integrierten Funktionen haben benutzerdefinierte Funktionen, die über PHP implementiert werden, völlig andere Ausführungsprozesse und Implementierungsprinzipien. Wie oben erwähnt, wissen wir, dass PHP-Code zur Ausführung in Opcodes übersetzt wird und Benutzerfunktionen keine Ausnahme bilden. Tatsächlich entspricht jede Funktion einem Satz Opcodes, und dieser Satz Anweisungen wird in zend_function gespeichert. Daher entspricht der Aufruf der Benutzerfunktion letztendlich der Ausführung einer Reihe von Opcodes.
》》Speichern lokaler Variablen und Implementierung der Rekursion
Wir wissen, dass die Funktionsrekursion über den Stapel abgeschlossen wird. In PHP wird dazu eine ähnliche Methode verwendet. Zend weist jeder PHP-Funktion eine aktive Symboltabelle (active_sym_table) zu, um den Status aller lokalen Variablen in der aktuellen Funktion aufzuzeichnen. Alle Symboltabellen werden in Form eines Stapels verwaltet. Bei jedem Aufruf einer Funktion wird eine neue Symboltabelle zugewiesen und auf den Stapel verschoben. Wenn der Aufruf endet, wird die aktuelle Symboltabelle vom Stapel entfernt. Dadurch werden Zustandserhaltung und Rekursion erreicht.
Für die Stack-Wartung hat Zend es hier optimiert. Weisen Sie vorab ein statisches Array der Länge N zu, um den Stapel zu simulieren. Diese Methode wird auch häufig in unseren eigenen Programmen verwendet. Diese Methode vermeidet die durch jeden Aufruf verursachte Speicherzuweisung. ZEND bereinigt am Ende des Funktionsaufrufs lediglich die Symboltabellendaten oben im aktuellen Stapel. Da die Länge des statischen Arrays N beträgt, verursacht das Programm keinen Stapelüberlauf, sobald die Funktionsaufrufebene N überschreitet. In diesem Fall weist zend die Symboltabelle zu und zerstört sie, was zu erheblichen Leistungseinbußen führt. In Zend beträgt der aktuelle Wert von N 32.Wenn wir PHP-Programme schreiben, ist es daher am besten, 32 Funktionsaufrufebenen nicht zu überschreiten. Wenn es sich um eine Webanwendung handelt, kann die Funktionsaufrufebene selbst natürlich tiefgreifend sein.
》》Die Übergabe von Parametern unterscheidet sich von der integrierten Funktion, die zend_parse_params aufruft, um Parameter abzurufen. Die Erfassung von Parametern in Benutzerfunktionen erfolgt über Anweisungen. Die Anzahl der Parameter einer Funktion entspricht der Anzahl der Anweisungen. Spezifisch für die Implementierung handelt es sich um eine gewöhnliche Variablenzuweisung. Aus der obigen Analyse ist ersichtlich, dass die Leistung der Benutzerfunktion im Vergleich zu den integrierten Funktionen relativ viel schlechter ist, da die Stapeltabelle selbst verwaltet wird und die Ausführung jeder Anweisung auch eine C-Funktion ist . Es wird später eine spezifische vergleichende Analyse geben. Wenn eine Funktion über eine entsprechende integrierte PHP-Funktion verfügt, versuchen Sie daher, die Funktion nicht selbst neu zu schreiben, um sie zu implementieren.
Baidu-Ingenieure sprechen über die Implementierungsprinzipien und Leistungsanalyse von PHP-Funktionen (1)
http://www.lai18.com/content/410091.html
Das Obige stellt die von Baidu-Ingenieuren erläuterten Implementierungsprinzipien und Leistungsanalysen von PHP-Funktionen vor (1), einschließlich Aspekten des Inhalts. Ich hoffe, dass es für Freunde hilfreich sein wird, die sich für PHP-Tutorials interessieren.