PHP Opcode: Verbessern Sie die Anwendungsleistung ohne Ihren Code zu ändern

Der PHP Opcode, der von der PHP-Engine generiert wird, ist stark von der Art und Weise beeinflusst, wie du dein Code schreibst, nicht nur hinsichtlich der Anzahl der Anweisungen, um eine Aufgabe zu erledigen. Klar hat das sehr viel Bedeutung und glaube, dass es für dich offensichtlich ist.

Was weniger offensichtlich sein könnte, ist dass selbst die Syntax des Codes den generierten Opcode völlig verändern kann, was der CPU der Maschine viel Overhead verursacht, um den exakt gleichen Code auszuführen.

In den letzten paar Jahren hat mein SaaS-Produkt sehr gewachsen und mir die Gelegenheit gegeben, immer tiefer in Optimierungsverfahren zu gehen, um meine Workload so effizient wie möglich abzuarbeiten.

Die Ergebnisse, die ich gesehen habe, sind beeindruckend und haben mir sehr geholfen, freies Cash Flow freizuschlagen, um meinen SaaS-Weg weiter zu entwickeln.

An dieser Stelle verarbeitet der PHP-Prozess in meinem SaaS-Produkt mehr als 1,2 Milliarden (mit „b“) Datenpakete pro Tag auf einer Maschine mit 2vCPU und 8GB Arbeitsspeicher. Ich verwende ein AWS-Autoskalierungs-Group, um mehr Flexibilität im Falle von unvorhersehbaren Spitzen zu haben, aber es fügt selten eine zweite Maschine hinzu (eine/zwei Mal die Woche).

Lass uns zum Thema des Artikels gehen. Ich glaube, du findest es sehr interessant.

Was ist PHP Opcode?

PHP Opcode steht für Operation Code, und es bezieht sich auf die niedrigeninstruktionen, die von der PHP-Engine nach der Kompilierung des von dir geschriebenen PHP-Quellcodes ausgeführt werden.

In PHP passiert die Kompilierung während der Laufzeit: Grundsätzlich wird der erste Mal, wenn dein Code von der PHP-Engine aufgenommen wird, in diesen maschinenfreundlichen Code kompiliert, cacht (also kompiliert die Engine nicht denselben Code erneut) und dann ausgeführt.

Dies ist eine einfache Darstellung des Prozesses:

PHP Opcode Caching

Das Cachen der PHP Opcodes ermöglicht es, drei Schritte in dem Prozess der Codeausführung zu sparen: die Parsing der Roh-PHP-Code, die Tokenisierung und die Kompilierung.

Sobald die Opcode zum ersten Mal generiert wurden, werden sie im Speicher gespeichert, sodass sie für spätere Anfragen wiederverwendet werden können. Dies reduziert die Notwendigkeit, dass der PHP-Motor den gleichen PHP-Code bei jeder Ausführung neu kompilieren muss, was einen erheblichen CPU- und Speicherverbrauch einschränkt.

Der am häufigsten verwendete Opcode-Cache in PHP ist OPCache, der ab PHP 5.5 standardmäßig bis zu den aktuellen Versionen enthalten ist. Er ist sehr effizient und weit verbreitet.

Das Cachen des vorkompilierten Skript-Bytecodes erfordert das Abweichen des Caches nach jeder Veröffentlichung. Dies liegt daran, dass, wenn geänderte Dateien die Bytecode-Version im Cache haben, PHP den alten Code bis zur Leere des Opcode-Caches aktiviert, sodass das neue Code erneut kompiliert wird und ein neues Cache-Element erzeugt wird.

Wie man PHP Opcode untersucht

Um zu verstehen, wie unterschiedliche Syntaxe Einfluss auf den Opcode des Skripts haben kann, müssen wir eine Methode finden, um den vom PHP-Motor generierten kompilierten Code zu erhalten.

Es gibt zwei Möglichkeiten, um den Opcode zu erhalten.

OPCache Native Funktionen

Wenn Sie die OPCache-Erweiterung auf Ihrem Rechner aktiviert haben, können Sie ihre native Funktionen verwenden, um den Opcode eines bestimmten PHP-Dateis zu erhalten:

PHP

 

VLD (Vulcan Logic Disassembler) PHP-Erweiterung

VLD ist eine populäre PHP-Erweiterung, die kompilierte PHP-Code dekompiliert und die Opcodes ausgibt. Es ist ein leistungsstarkes Werkzeug zur Verstehen, wie PHP Ihren Code interpretiert und ausführt. Nach der Installation können Sie ein PHP-Skript mit VLD aktiviert mit dem Befehl php mit den -d Optionen ausführen:

Shell

 

Der Output wird detaillierte Informationen über die kompilierten Opcodes enthalten, einschließlich jeder Operation, seiner zugehörigen Codezeile und mehr.

Verwenden Sie 3v4l (Akronym für EVAL)

3v4l ist eine sehr nützliche Online-Tool, das Ihnen erlaubt, die Opcode, die durch PHP-Code generiert werden, zu betrachten. Es ist im Grunde ein PHP-Server mit VLD installiert, der die VLD-Ausgabe erfasst und die Opcode im Browser anzeigt.

Bei seiner Freiheit nutzen wir dieses Online-Tool für die nächsten Analysen.

Wie man effiziente PHP-Opcode generiert

3v4l ist perfekt, um zu verstehen, wie die von uns verwendete Code-Syntax die resultierenden PHP-Opcode in einer guten oder schlechten Weise beeinflussen kann. Beginnen wir mit dem Einfügen des Codes unten in 3v4l. Behalten Sie die Konfiguration „alle unterstützten Versionen“ bei und klicken Sie auf „eval“.

PHP

 

Nach der Ausführung des Codes wird ein Tab-Menü am unteren Bildschirm erscheinen. Navigieren Sie zum VLD Tab, um die entsprechenden Opcode可视化.

Shell

 

Beachten Sie, dass die erste Operation INIT_NS_FCALL_BY_NAME ist. Der Interpreter baut den Namen der Funktion aus dem Namespace des aktuellen Dateisystems auf, aber er existiert nicht im App\Example-Namespace — wie funktioniert das denn eigentlich?

Der Interpreter wird prüfen, ob die Funktion im aktuellen Namespace existiert. Wenn nicht, versucht er, die entsprechende Kernfunktion aufzurufen.

Hier haben wir die Gelegenheit, dem Interpreter zu sagen, dass er diese doppelte Überprüfung vermeidet und direkt die Kernfunktion ausführt.

Versuchen Sie, ein Backslash (\) vor strlen zu addieren und klicken Sie auf “eval”:

PHP

 

Im VLD-Tab können Sie nun die Opcode mit nur einer Anweisung sehen.

Weil Sie den genauen Ort der Funktion kommuniziert haben, muss er nicht an irgendeine Fallback-Option denken.

Wenn Sie das Backslash nicht verwenden möchten, können Sie die Funktion wie jede andere Klasse aus dem Wurzel-Namespace importieren:

PHP

 

Nutzen Sie automatische Opcode-Optimierungen

Es gibt auch viele interne Automatismen des PHP-Engines, um optimierte Opcode für die Beurteilung statischer Ausdrücke im Voraus zu generieren. Dies war einer der wichtigsten Gründe für die großartige Leistungsverbesserung von PHP seit Version 7.x.

Bei Kenntnis dieser Dynamik kann es Ihnen wirklich helfen, den Ressourcenverbrauch zu reduzieren und Kosten zu sparen. Nachdem ich diese Forschung durchführte, begann ich diese Tricks im gesamten Code zu verwenden.

Lassen Sie mich Ihnen ein Beispiel mit PHP-Konstanten zeigen. Führen Sie dieses Skript in 3v4l aus:

PHP

 

Schauen Sie sich die ersten zwei Zeilen der PHP-Opcode an:

FETCH_CONSTANT versucht, den Wert von PHP_OS aus dem aktuellen Namespace zu erhalten, und sucht in dem globalen Namespace, da er hier nicht existiert. Dann führt die Anweisung IS_IDENTICAL den IF-Ausdruck aus.

Versuchen Sie nun, einen Backslash zu einer Konstante hinzuzufügen:

PHP

 

Wie Sie in der Opcode sehen können, muss der Engine nicht mehr versuchen, die Konstante abzurufen, weil sich nun klar ergibt, wo sie ist, und da es sich um einen statischen Wert handelt, hat er sie bereits im Speicher.

Außerdem ist der IF-Ausdruck verschwunden, weil das andere Ende des IS_IDENTICAL-Ausdrucks eine statische Zeichenkette ist (`’Linux’`), sodass der IF als „true“ markiert werden kann, ohne dass auf jeder Ausführung das Interpretieren überlastet werden muss.

Daher haben Sie viel Macht, um die Leistung Ihres PHP-Codes letztendlich zu beeinflussen.

Fazit

Ich hoffe, es war ein interessantes Thema. Wie ich am Anfang des Artikels erwähnte, profitiere ich erheblich von dieser Taktik und sie werden auch in unseren Paketen verwendet.

Sie können hier einen Beispiel sehen, wie ich diese Tipps in unserem PHP-Paket angewendet habe, um seine Leistung zu optimieren.

Wenn Sie mehr über die Herausforderungen lernen möchten, mit denen ein von Entwicklern getriebenes Unternehmen befasst ist, können Sie mich auf LinkedIn verfolgen.

Source:
https://dzone.com/articles/php-opcode-improve-application-performance