PHP Opcode: コードを変更せずにアプリケーションのパフォーマンスを改善する方法

PHPエンジンによって生成されるOPコードは、PHPのソースコードを書く方法に強く依存しており、タスクを完了するためのステートメントの数だけでなく、明らかに大切であること、そしてこれはあなたにははっきりしていると思います。

もっともはっきりしないのは、それぞれのコードの構文が、生成されるOPコードを完全に変更し、同じコードを実行するためにマシンのCPUには大幅なオーバーヘッドを負わせることです。

この数年間、私のSaaS製品は大幅に成長し、私にはより深く最適化技術に取り組む機会を与えています。

私が見た結果は印象的で、私のSaaSの開発を続けるために自由现金流を解放する上で大変助かりました。

今のところ、私のSaaS製品内のPHPプロセスは2vCPUと8GBのメモリのマシンで日に12億(“b”である)のデータパケットを処理しています。

AWSの自動スケーリンググループを使用して、予想外のスパイクに対する柔軟性を持つことができますが、ほとんど2回(週の1/2回)しか追加しないです。

今回の記事のテーマに取り挂かりましょう。これは非常に興味深いことになると思います。

PHP Opcodeとは何か?PHP opcodeは、PHPのソースコードがコンパイルされた後、PHPエンジンによって実行される低レベルの命令を指します。

PHPでは、コードのコンパイルは実行時に行われます。基本的に、PHPエンジンによってあなたのコードが最初に取られると、それがこのマシンによく理解できるコードにコンパイルされ、キャッシュされます(すでに同じコードを再コンパイルしないように)、そして実行されます。

これはプロセスの簡単な表現です:

PHPオペコードキャッシング

PHPのオペコードをキャッシュすることで、コードの実行プロセスにおいて3つのステップを省くことができます:原始的なPHPコードの解析、トークン化、とコンパイル。

最初にオペコードを生成すると、メモリに保存され、次のリクエストで再利用されることができます。これにより、PHPエンジンが同じPHPコードを再コンパイルする必要がなくなり、CPUとメモリの消費を大幅に削減することができます。

PHPで最も一般的に使用されるオペコードキャッシングはOPCacheで、PHP 5.5から最新のバージョンまでデフォルトで含まれています。これは非常に効果的で、幅広くサポートされています。

预コンパイルされたスクリプトのバイトコードをキャッシュするためには、デプロイの後にキャッシュを無効化する必要があります。なぜなら、変更されたファイルがキャッシュにバイトコードのバージョンを持っている場合、PHPはキャッシュを破棄する前には旧いバージョンのコードを実行し続けます。したがって、新しいコードは再びコンパイルされ、新しいキャッシュアイテムを生成します。

PHPオペコードを調査する方法

DIFFERENT SYNTAX can impact the script’s opcode different ways we need a way to get the compiled code generated by the PHP engine.

GETTING OPCODE There are two ways of getting the opcode.

OPCache Native Functions

If you have the OPCache extension enabled on your machine, you can use its native functions to get the opcode of a specific PHP file:

PHP

 

VLD (Vulcan Logic Disassembler) PHP Extension

VLDは、コンパイルされたPHPコードを分解し、オプコードを出力するPHPの拡張機能で人気があります。これは、PHPがあなたのコードをどのように解釈し、実行するのか理解するのに強力なツールです。インストールすると、PHPスクリプトをVLDを有効にして実行することができます。これは、phpコマンドを使用し、-dオプションを追加します。

Shell

 

出力には、コンパイルされたオプコードに関する詳細な情報が含まれます。これには、各操作、それに関連付けられたコード行などが含まれます。

3v4lを使用する

3v4lは、PHPコードによって生成されるオプコードを表示することができる非常に便利なオンラインツールです。基本的には、VLDをインストールしたPHPサーバーですので、VLDの出力を取得し、ブラウザ内でオプコードを表示します。

これは無料であるため、次の分析でこのオンラインツールを使用します。

効率的なPHPオプコードを生成する方法

3v4lは、私たちが使用するコード構文が、結果のPHPオプコードにどのように影響を与えるか理解するのに最適なツールです。以下のコードを3v4lに貼り付けます。設定を“すべてのサポートされるバージョン”とし、“eval”をクリックします。

PHP

 

コードを実行すると、下部にタブメニューが表示されます。このタブメニューにVLDタブを移動し、対応するオプコードを視覚化します。

Shell

 

最初の操作はINIT_NS_FCALL_BY_NAMEであることに注意してください。インタープリターは現在のファイルの名前空間を使って関数名を構築しますが、App\Example名前空間には存在しません — では、どのように動作するのでしょうか?

インタープリターは関数が現在の名前空間に存在するかどうかを確認します。存在しない場合は、対応するコア関数を呼び出そうとします。

ここで、インタープリターに二重チェックを避けて直接コア関数を実行するように指示する機会があります。

strlenの前にバックスラッシュ(\)を追加して「eval」をクリックしてください:

PHP

 

VLDタブで、一文だけのオペコードを見ることができます。

関数の正確な位置を伝えたため、フォールバックを考慮する必要はありません。

バックスラッシュを使いたくない場合は、他のクラスと同様にルート名前空間から関数をインポートできます:

PHP

 

自動オペコード最適化を活用する

PHPエンジンの内部には静的表現を事前に評価して最適化されたオペコードを生成する多くの自動機構があります。これはPHPのバージョン7.x以降の大きなパフォーマンス向上の最も重要な理由の一つでした。

これらの動的特性を理解することで、リソース消費を削減し、コストを削減するのに本当に役立ちます。この調査を行った後、コード全体でこれらのテクニックを使い始めました。

PHP定数を使用した例をお見せしましょう。このスクリプトを3v4lで実行してください:

PHP

 

PHPオペコードの最初の2行を見てください:

FETCH_CONSTANTは、現在の命名空間からPHP_OSの値を取得しようと試みます。存在しない場合、そこから全局命名空間を探し出します。次に、IS_IDENTICAL命令はIF文を実行します。

今度は、定数に反斜杠を追加してみてください。

PHP

 

Opcodeを見ると、エンジンは定数を取得する必要がないことがわかります。なぜなら、それがどこにあるかは明确で、静的な値であるため、すでにメモリに保持されています。

また、IF文は消えました。なぜなら、IS_IDENTICAL命令の他方は静的な文字列(‘Linux‘)であるため、IF文は“true”としてマークされ、每一次の実行でそれを解釈するオーバーヘッドがないです。

これが、PHPコードの最終的な性能に大きな影響力を持つことができる理由です。

結論

このトピックが興味深いものでした。記事の初めで述べた通り、私はこの戦略を用いて大変有益なことをしています。そして、実際、私たちのパッケージでも使用しています。

私がこのPHPパッケージの性能最適化にこれらの手順を使用した例をここで見ることができます

私をLinkedInでフォローして、開発者中心の会社の構築に関する課題について学ぶことができます。

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