Opcode PHP yang dijana oleh enjin PHP sangat dipengaruhi oleh cara anda menulis kod anda. Bukan sahaja dari segi bilangan kenyataan untuk menyelesaikan sesuatu tugasan. Jelas sekali ia amat penting dan saya rasa ia jelas kepada anda.
Apa yang kurang jelas ialah sintaks kod boleh menukar sepenuhnya kod opkod yang dijana menyebabkan banyak overhed untuk CPU mesin melaksanakan kod yang sama.
Dalam beberapa tahun kebelakangan ini, produk SaaS saya telah berkembang dengan pesat, dan ia telah memberi saya peluang untuk mendalami teknik pengoptimuman untuk menjalankan beban kerja saya secekap yang mungkin.
Hasil yang saya lihat sangat mengagumkan dan banyak membantu saya dalam membuka kunci aliran tunai percuma untuk terus membangunkan perjalanan SaaS saya.
Pada ketika ini proses PHP dalam produk SaaS saya sedang memproses lebih daripada 1.2 bilion (dengan B) paket data setiap hari pada mesin dengan 2vCPU dan memori 8GB. Saya menggunakan kumpulan autoscaling AWS untuk mempunyai lebih fleksibiliti sekiranya berlaku lonjakan yang tidak dapat diramalkan, tetapi ia jarang menambah mesin kedua (satu/dua kali seminggu).
Untuk lebih banyak artikel teknikal, anda boleh mengikuti saya di Linkedin atau X.
Baru-baru ini saya juga menulis tentang pemindahan pelayan Inspektor kepada kejadian ARM: https://inspector.dev/inspector-adoption-of-graviton-arm-instances-and-what-results-weve-seen/
Mari kita masuk ke topik artikel. Saya rasa anda akan mendapatinya sangat menarik.
Opcode PHP bermaksud kod operasi, dan ia merujuk kepada arahan peringkat rendah yang dilaksanakan oleh enjin PHP selepas kod sumber PHP yang anda tulis telah disusun.
Dalam PHP, penyusunan kod berlaku pada masa jalankan, pada asasnya pada kali pertama kod anda diambil oleh enjin PHP ia akan dikompilasi ke dalam kod mesra mesin ini, dicache, supaya enjin tidak menyusun kod yang sama lagi, dan kemudian dilaksanakan.
Ini ialah gambaran ringkas proses:
Caching opcode PHP membolehkan anda menyimpan tiga langkah dalam proses melaksanakan kod: Menghuraikan kod PHP mentah, Tokenisasi dan Penyusunan.
Setelah opcode dijana buat kali pertama, ia disimpan dalam memori supaya ia boleh digunakan semula dalam permintaan seterusnya. Ini mengurangkan keperluan untuk enjin PHP untuk menyusun semula kod PHP yang sama setiap kali ia dilaksanakan, menjimatkan banyak penggunaan CPU dan memori.
Cache opcode yang paling biasa digunakan dalam PHP ialah OPCache, dan ia disertakan secara lalai sejak PHP 5.5 sehingga versi terkini. Ia sangat cekap dan disokong secara meluas.
Caching the precompiled script bytecode requires invalidating the cache after every deployment. Because if changed files have the bytecode version in the cache PHP will continue to run the old version of the code. Until you purge the opcode cache so the new code will be compiled again generating a new cache item.
To understand how different syntax can impact the script's opcode we need a way to grab the compiled code generated by the PHP engine.
There are two ways of getting the opcode.
If you have the OPCache extension enable on your machine you can use its native functions to get the opcode of a specific php file:
// 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 is a popular PHP extension that disassembles compiled PHP code and outputs the opcode. It’s a powerful tool for understanding how PHP interprets and executes your code.Once installed you can run a PHP script with VLD enabled by using the php command with -d options:
php -d vld.active=1 -d vld.execute=0 yourscript.php
The output will include detailed information about the compiled opcode, including each operation, its associated line of code, and more.
3v4l is a very useful online tool that allows you to view the opcode generated by a PHP code you type into the editor. It basically is a PHP server with VLD installed so it can grab the VLD output and show you the opcode into the browser.
As it's free distributed we’ll use this online tool for the next analyses.
3v4l is perfect to understand how the code syntax we use can influence the resulting PHP opcode in a good or bad way.Let’s start pasting the code below into 3v4l. Keep the configuration "all supported versions" and click on "eval".
<?php namespace App; strlen('ciao');
After executing the code a tab menu will appear on the bottom. Navigate to the VLD tab to visualize the correspondent OPcode.
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
Note that the first operation is INIT_NS_FCALL_BY_NAME. The interpreter constructs the name of the function using the namespace of the current file. But it doesn’t exist in the AppExample namespace, so how does it work?
The interpreter will check if the function exists in the current namespace. If it doesn’t it tries to call the corresponding core function.
Here we have the opportunity to tell the interpreter to avoid this double check and directly execute the core function.
Try to add a backslash () before strlen and click "eval":
<?php namespace App; \strlen('ciao');
In the VLD tab you can now see the opcode with just one statement.
line #* E I O op fetch ext return operands ------------------------------------------------------------------------------------- 5 0 E > > RETURN 1
It's because you communicated the exact location of the function, so it doesn’t need to consider any fallback.
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
Atas ialah kandungan terperinci PHP opcode – Meningkatkan prestasi aplikasi tanpa mengubah kod anda. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!