Opcode PHP yang dijana oleh enjin PHP sangat dipengaruhi oleh cara anda menulis kod anda. Bukan sahaja dari segi bilangan pernyataan untuk menyelesaikan sesuatu tugas. 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, kompilasi kod berlaku semasa runtime, pada asasnya pada kali pertama kod anda diambil oleh enjin PHP ia akan dihimpun ke dalam kod mesra mesin ini, dicache, jadi 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 CPU dan penggunaan 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.
Mencache kod bait 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.
Jika tidak suka menggunakan garis miring terbalik, anda boleh mengimport fungsi seperti mana-mana kelas lain dari ruang nama akar:
// 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']);
Terdapat juga banyak automatik dalaman enjin PHP untuk menjana kod opcode yang dioptimumkan yang menilai ungkapan statik terlebih dahulu. Ini adalah salah satu sebab terpenting peningkatan prestasi PHP yang hebat sejak versi 7.x
Menyedari dinamik ini benar-benar boleh membantu anda mengurangkan penggunaan sumber dan mengurangkan kos. Sebaik sahaja saya membuat penyelidikan ini, saya mula menggunakan helah ini sepanjang kod.
Biar saya tunjukkan kepada anda contoh menggunakan pemalar PHP. Jalankan skrip ini menjadi 3v4l:
php -d vld.active=1 -d vld.execute=0 yourscript.php
Lihat dua baris pertama opcode PHP:
<?php namespace App; strlen('ciao');
FETCH_CONSTANT cuba dapatkan nilai PHP_OS daripada ruang nama semasa dan ia akan melihat ke dalam ruang nama global kerana ia tidak wujud di sini. Kemudian arahan IS_IDENTICAL melaksanakan pernyataan IF.
Sekarang cuba tambahkan garis miring ke belakang pada pemalar:
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
Seperti yang anda lihat dalam opcode, enjin tidak perlu cuba mengambil pemalar kerana sekarang ia jelas di mana ia berada, dan memandangkan ia adalah nilai statik, ia sudah mempunyainya dalam ingatan.
Juga penyataan IF hilang kerana bahagian lain pernyataan IS_IDENTITCAL ialah rentetan statik ('Linux') jadi IF boleh ditandakan sebagai "benar" tanpa overhed untuk mentafsirkannya pada setiap pelaksanaan.
Inilah sebabnya anda mempunyai banyak kuasa untuk mempengaruhi prestasi muktamad kod PHP anda.
Saya harap ia adalah topik yang menarik, seperti yang saya nyatakan pada awal artikel saya mendapat banyak faedah daripada menggunakan taktik ini dan sebenarnya ia juga digunakan dalam pakej kami.
Anda boleh lihat di sini contoh cara saya menggunakan petua ini dalam pakej PHP kami untuk mengoptimumkan prestasinya: https://github.com/inspector-apm/inspector-php/blob/master/src/Inspector.php# L302
Untuk lebih banyak artikel teknikal, anda boleh mengikuti saya di Linkedin atau X.
Inspektor ialah alat Pemantauan Pelaksanaan Kod yang direka khusus untuk pembangun perisian. Anda tidak perlu memasang apa-apa di peringkat pelayan, cuma pasang pakej Laravel atau Symfony dan anda sudah bersedia untuk pergi.
Jika anda sedang mencari pemantauan HTTP, cerapan pertanyaan pangkalan data dan keupayaan untuk memajukan makluman dan pemberitahuan ke dalam persekitaran pemesejan pilihan anda, cuba Inspektor secara percuma. Daftar akaun anda.
Atau ketahui lebih lanjut di tapak web: 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!