Heim > Artikel > Backend-Entwicklung > PHP-Opcode – Verbessern Sie die Anwendungsleistung, ohne Ihren Code zu ändern
Der von der PHP-Engine generierte PHP-Opcode wird stark von der Art und Weise beeinflusst, wie Sie Ihren Code schreiben. Nicht nur im Hinblick auf die Anzahl der Anweisungen zur Erfüllung einer Aufgabe. Offensichtlich ist es sehr wichtig, und ich denke, es ist für Sie offensichtlich.
Was weniger offensichtlich sein könnte, ist, dass selbst die Syntax des Codes den generierten Opcode vollständig ändern kann, was einen hohen Overhead für die CPU der Maschine verursacht, um genau denselben Code auszuführen.
In den letzten Jahren ist mein SaaS-Produkt stark gewachsen und es hat mir die Möglichkeit gegeben, immer tiefer in die Optimierungstechniken einzusteigen, um meine Arbeitslast so effizient wie möglich auszuführen.
Die Ergebnisse, die ich gesehen habe, sind beeindruckend und haben mir sehr dabei geholfen, freien Cashflow freizusetzen, um meine SaaS-Reise weiterzuentwickeln.
Zu diesem Zeitpunkt verarbeitet der PHP-Prozess in meinem SaaS-Produkt täglich mehr als 1,2 Milliarden (mit B) Datenpakete auf einer Maschine mit 2vCPU und 8GB Arbeitsspeicher. Ich verwende eine AWS-Autoscaling-Gruppe, um bei unvorhersehbaren Spitzen mehr Flexibilität zu haben, aber sie fügt selten eine zweite Maschine hinzu (ein- oder zweimal pro Woche).
Für weitere technische Artikel können Sie mir auf Linkedin oder X folgen.
Kürzlich habe ich auch über die Migration der Inspector-Server auf ARM-Instanzen geschrieben: https://inspector.dev/inspector-adoption-of-graviton-arm-instances-and-what-results-weve-seen/
Lassen Sie uns auf das Thema des Artikels eingehen. Ich denke, Sie werden es sehr interessant finden.
PHP-Opcode steht für Operationscode und bezieht sich auf die Low-Level-Anweisungen, die von der PHP-Engine ausgeführt werden, nachdem der von Ihnen geschriebene PHP-Quellcode kompiliert wurde.
In PHP erfolgt die Codekompilierung zur Laufzeit. Wenn Ihr Code zum ersten Mal von der PHP-Engine übernommen wird, wird er in diesen maschinenfreundlichen Code kompiliert und zwischengespeichert, damit die Engine denselben Code nicht erneut kompiliert dann ausgeführt.
Dies ist eine einfache Darstellung des Prozesses:
Durch das Zwischenspeichern des PHP-Opcodes können Sie drei Schritte bei der Ausführung des Codes einsparen: Parsen des rohen PHP-Codes, Tokenisierung und Kompilierung.
Sobald der Opcode zum ersten Mal generiert wird, wird er im Speicher gespeichert, sodass er in nachfolgenden Anforderungen wiederverwendet werden kann. Dies reduziert die Notwendigkeit, dass die PHP-Engine bei jeder Ausführung denselben PHP-Code neu kompilieren muss, was viel CPU- und Speicherverbrauch spart.
Der am häufigsten verwendete Opcode-Cache in PHP ist OPCache und ist seit PHP 5.5 bis zu neueren Versionen standardmäßig enthalten. Es ist hocheffizient und wird weithin unterstützt.
Mencache kod byte skrip yang diprakompil memerlukan cache tidak sah selepas setiap penggunaan. Kerana jika fail yang diubah mempunyai versi bytecode dalam cache PHP akan terus menjalankan versi lama kod tersebut. Sehingga anda membersihkan cache opcode supaya kod baharu akan disusun semula untuk menghasilkan item cache baharu.
Untuk memahami cara sintaks yang berbeza boleh memberi kesan kepada opcode skrip, kami memerlukan cara untuk merebut kod terkumpul yang dijana oleh enjin PHP.
Terdapat dua cara untuk mendapatkan opcode.
Jika anda mempunyai sambungan OPCache yang didayakan pada mesin anda, anda boleh menggunakan fungsi asalnya untuk mendapatkan opcode fail php tertentu:
// Force compilation of a script opcache_compile_file(__DIR__.'/yourscript.php'); // Get OPcache status $status = opcache_get_status(); // Inspect the script's entry in the cache print_r($status['scripts'][__DIR__.'/yourscript.php']);
VLD ialah sambungan PHP popular yang menyahhimpun kod PHP yang disusun dan mengeluarkan opcode. Ia adalah alat yang berkuasa untuk memahami cara PHP mentafsir dan melaksanakan kod anda. Setelah dipasang, anda boleh menjalankan skrip PHP dengan VLD didayakan dengan menggunakan arahan php dengan pilihan -d:
php -d vld.active=1 -d vld.execute=0 yourscript.php
Output akan menyertakan maklumat terperinci tentang opcode yang disusun, termasuk setiap operasi, baris kod yang berkaitan dan banyak lagi.
3v4l ialah alat dalam talian yang sangat berguna yang membolehkan anda melihat opcode yang dijana oleh kod PHP yang anda taip ke dalam editor. Ia pada asasnya ialah pelayan PHP dengan VLD dipasang supaya ia boleh merebut output VLD dan menunjukkan kepada anda opcode ke dalam penyemak imbas.
Memandangkan ia diedarkan secara percuma, kami akan menggunakan alat dalam talian ini untuk analisis seterusnya.
3v4l sesuai untuk memahami cara sintaks kod yang kami gunakan boleh mempengaruhi opcode PHP yang terhasil dengan cara yang baik atau buruk. Mari mula menampal kod di bawah ke dalam 3v4l. Kekalkan konfigurasi "semua versi yang disokong" dan klik pada "eval".
<?php namespace App; strlen('ciao');
Selepas melaksanakan kod menu tab akan muncul di bahagian bawah. Navigasi ke tab VLD untuk menggambarkan kod OP koresponden.
line #* E I O op fetch ext return operands ------------------------------------------------------------------------------------- 5 0 E > INIT_NS_FCALL_BY_NAME 'App%5CSpace%5Cstrlen' 1 SEND_VAL_EX 'ciao' 2 DO_FCALL 0 3 > RETURN 1
Perhatikan bahawa operasi pertama ialah INIT_NS_FCALL_BY_NAME. Jurubahasa membina nama fungsi menggunakan ruang nama fail semasa. Tetapi ia tidak wujud dalam ruang nama AppExample, jadi bagaimanakah ia berfungsi?
Jurubahasa akan menyemak sama ada fungsi itu wujud dalam ruang nama semasa. Jika tidak, ia cuba memanggil fungsi teras yang sepadan.
Di sini kami berpeluang untuk memberitahu jurubahasa untuk mengelakkan semakan dua kali ini dan terus melaksanakan fungsi teras.
Cuba tambahkan sengkang terbalik () sebelum strlen dan klik "eval":
<?php namespace App; \strlen('ciao');
Dalam tab VLD kini anda boleh melihat opcode dengan hanya satu pernyataan.
line #* E I O op fetch ext return operands ------------------------------------------------------------------------------------- 5 0 E > > RETURN 1
Ini kerana anda telah menyampaikan lokasi sebenar fungsi tersebut, jadi ia tidak perlu mempertimbangkan sebarang sandaran.
If don't like to use the the backslash, you can import the function like any other class from the root namespace:
<?php namespace App; use function strlen; strlen('ciao');
There are also a lot of internal automatisms of the PHP engine to generate an optimized opcode evaluating static expressions in advance. This was one of the most important reasons of the great performance improvement of PHP since the version 7.x
Being aware of these dynamics can really help you reduce resource consumption and cut costs. Once I made this research, I started using these tricks throughout the code.
Let me show you an example using PHP constants. Run this script into 3v4l:
<?php namespace App; if (PHP_OS === 'Linux') { echo "Linux"; }
Take a look at the first two lines of the PHP opcode:
line #* E I O op fetch ext return operands ------------------------------------------------------------------------------------- 5 0 E > FETCH_CONSTANT ~0 'App%5CPHP_OS' 1 IS_IDENTICAL ~0, 'Linux' 2 > JMPZ ~1, ->4 6 3 > ECHO 'Linux' 7 4 > > RETURN 1
FETCH_CONSTANT try to get the value of PHP_OS from the current namespace and it will look into the global namespace as it doesn’t exist here. Then the IS_IDENTICAL instruction executes the IF statement.
Now try adding the backslash to constant:
<?php namespace App; if (\PHP_OS === 'Linux') { echo "Linux"; }
As you can see in the opcode the engine doesn't need to try to fetch the constant because now it's clear where it is, and since it's a static value it already has it in memory.
Also the IF statement disappeared because the other side of the IS_IDENTITCAL statement is a static string ('Linux') so the IF can be marked as "true" without the overhead of interpreting it on every execution.
This is why you have a lot of power to influence the ultimate performance of your PHP code.
I hope it was an interesting topic, as I mentioned at the beginning of the article I'm getting a lot of benefits from using this tactic and in fact they are also used in our packages.
You can see here an example of how I used this tips in our PHP package to optimize its performance: https://github.com/inspector-apm/inspector-php/blob/master/src/Inspector.php#L302
For more technical articles you can follow me on Linkedin or X.
Inspector is a Code Execution Monitoring tool specifically designed for software developers. You don't need to install anything at the server level, just install the Laravel or Symfony package and you are ready to go.
If you are looking for HTTP monitoring, database query insights, and the ability to forward alerts and notifications into your preferred messaging environment, try Inspector for free. Register your account.
Or learn more on the website: https://inspector.dev
Das obige ist der detaillierte Inhalt vonPHP-Opcode – Verbessern Sie die Anwendungsleistung, ohne Ihren Code zu ändern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!