Heim  >  Artikel  >  Backend-Entwicklung  >  PHP-Opcode – Verbessern Sie die Anwendungsleistung, ohne Ihren Code zu ändern

PHP-Opcode – Verbessern Sie die Anwendungsleistung, ohne Ihren Code zu ändern

Linda Hamilton
Linda HamiltonOriginal
2024-11-14 10:13:01127Durchsuche

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.

Was ist der PHP-Opcode?

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:

PHP opcode – Improve application performance without changing your code

PHP-Opcode-Caching

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.

Bagaimana untuk menyiasat opcode PHP

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.

OPCache fungsi asli

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']);

Sambungan php VLD (Vulcan Logic Disassembler).

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.

Gunakan 3v4l (Akronim untuk EVAL)

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.

Bagaimana untuk menjana opcode PHP yang cekap

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');

Leverage Automatic Opcode Optimizations

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.

Monitor your PHP application for free

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

PHP opcode – Improve application performance without changing your code

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn