PHP のパフォーマンスに関する最適化のヒントはインターネット上に無数にありますので、参照用にリストを作成する必要があります。
著者が収集したこれらのスキルは幅広い情報源から得たものであり、その完全性は保証されません。ボリュームが大きいため、これらの最適化手法はテストされていません。結局のところ、これらのスキルが役立つかどうかは、PHP が置かれている独自の環境に依存します。
1. ボトルネックを見つける (ボトルネックを見つける)
パフォーマンスの問題に直面したとき、最初のステップは常に問題の原因を見つけることであり、トリックのリストを調べることではありません。ボトルネックの原因を特定し、ターゲットを見つけて修正を実装し、再テストします。ボトルネックを見つけることは長征の最初のステップにすぎません。最も重要な最初のステップでボトルネックを見つけるのに役立つことを願って、ここではいくつかの一般的なテクニックを紹介します。
- モニタリング手法(モニタリングトレジャーなど)を利用してベンチマーク(ベンチマークテスト)やモニタリングを実施する ネットワーク、特にネットワークの状態は急激に変化するため、うまくやれば5分程度でボトルネックを見つけることができます。
- コードを分析します。コードのどの部分に最も時間がかかるかを理解し、その部分にさらに注意を払う必要があります。
- ボトルネックを見つけるには、各リソース要求(ネットワーク、CPU、メモリ、共有メモリ、ファイルシステム、プロセス管理、ネットワーク接続など) を確認します。
- 最初に反復構造と複雑なコードのベンチマークを行います。
- 実際の負荷の下で実際のデータを使用して実際のテストを実行します。可能であれば実稼働サーバーを使用してください。
2. キャッシング
キャッシュがパフォーマンスの問題に対する最も効果的な解決策の 1 つであると考える人もいます。次のことを試してください。
- スクリプトがアクセスされるたびに再コンパイルされないように、OPCODE (オペレーション コード) キャッシュを使用します。たとえば、Windows プラットフォームで Windows キャッシュ拡張機能を有効にします。オペコード、ファイル、相対パス、セッション データ、ユーザー データをキャッシュできます。
- マルチサーバー環境で分散キャッシュの使用を検討する
- imap_header() を呼び出す前に imap_headers() を呼び出してください。
3. コンパイル vs. インタプリタ (コンパイル vs. インタプリタ)
PHP ソース コードをマシンコードにコンパイルします。動的解釈は同じコンパイルを実行しますが、それは 1 行ずつ実行されます。オペコードへのコンパイルは妥協の選択であり、PHP ソース コードをオペコードに変換し、その後オペコードをマシン コードに変換できます。以下は、コンパイルと解釈に関する関連ヒントです。
- 公開する前に、PHP コードをマシンコードにコンパイルします。オペコード キャッシュは最良の選択ではありませんが、解釈されたキャッシュよりも優れています。あるいは、PHP コードを C 拡張機能にコンパイルすることを検討してください。
- PHP のオペコード コンパイラ (bcompiler) はまだ本番環境では利用できませんが、開発者は http://php.net/manual/en/book.bcompiler.php に従う必要があります。
4. コンテンツの削減
より少なく、より速く。これらのヒントは、コードを減らすのに役立ちます。
- ページあたりの機能が少ない
- Web コンテンツをクリーンアップする
- 解釈的に実行した場合、コメントやその他の空白をクリーンアップします。
- データベースクエリの削減
5. マルチスレッドとマルチプロセッシング
速いものから遅いものまでは次のとおりです。
- マルチスレッド (単一プロセス内)
- マルチプロセッシング (pcntl_fork、スケジュールされたタスクなど)
- 単一プロセス (行ごと)
PHP はマルチスレッドをサポートしていませんが、C でマルチスレッド PHP 拡張機能を作成できます。複数のプロセスを使用したり、複数のプロセスをシミュレートする方法はいくつかありますが、サポートがあまり良くなく、単一プロセスよりも遅くなる可能性があります。
6. ストリングス
文字列操作は、ほとんどのプログラミング言語で最も一般的に使用される操作の 1 つです。文字列処理を少し速くするのに役立ついくつかのトリックを次に示します。
- PHP の接続操作 (ポイント操作) は最も高速な接続方法です
- 印刷では文字列の連結を避け、カンマで区切って ECHO を使用してください。
- 可能な限り、正規表現の代わりに str_ という接頭辞を付けた文字列関数を使用してください。
- pos() は preg_mach() や ereg() よりも高速です
- 文字列を二重引用符で囲むよりも一重引用符で囲んだほうが速いという人もいますが、違いがないと言う人もいます。もちろん、文字列内の変数を引用符で囲みたい場合は、一重引用符は役に立ちません。
- 文字列の長さが特定の値 (5 など) 未満であるかどうかを判断したい場合は、isset($s[4])<5 を使用してください。
- 複数の小さな文字列を 1 つの大きな文字列に連結する必要がある場合は、まず ob_start 出力バッファを有効にしてから、echo を使用してバッファに出力し、完了後に ob_get_contents を使用して文字列を読み取ります。
7. 正規表現
正規表現は、文字列を比較および検索するための柔軟で多様な方法を提供しますが、パフォーマンスのオーバーヘッドは実際には低くありません。
- 可能な限り、正規表現の代わりに STR_ という接頭辞が付いた文字列処理関数を使用してください。
- [aeiou] を使用して (a|e|i|o|u) ではありません
- シンプルな正規表現ほど高速です
- 可能な場合は PCRE_DOTALL 修飾子を設定しないでください
- . の代わりに^. を使用してください。
- 正規表現を簡略化します。(例: (a+) の代わりにa を使用します
8. 反復構成要素 (for、while)
イテレーション (反復、ループ) は構造化プログラミングの最も基本的な方法であり、これを使用しないプログラムを想像するのは困難です。反復構造のパフォーマンスを向上させるのに役立ついくつかのトリックを次に示します。
- コードを可能な限りループ外に移動します (関数呼び出し、SQL クエリなど)。
- for(i=0;i<maxval;i++) の代わりに i=maxval;while(i–) を使用すると、1 回の操作を減らすことができ、maxval が関数呼び出しであるかどうかがより明確になります。
- foreach を使用してコレクションと配列を反復する
9. 選択構造 (if、switch)
反復構造と同様に、選択構造も最も基本的な構造化プログラミング手法です。次のテクニックによりパフォーマンスが向上する可能性があります。
- スイッチと else-if では、最近頻繁に true として現れるものを最初にリストし、めったに true として現れないものを後にリストする必要があります。
- if-else は swtich/case よりも速いという人もいますが、もちろん反対する人もいます。
- else if を elseif に置き換えます。
10. 関数とパラメータ
関数のコードをより小さな関数コードに分割すると、冗長性が削除され、コードが読みやすくなります。しかし、その代償はどのようなものでしょうか? 関数をより効果的に使用するためのヒントをいくつか紹介します。
オブジェクトと配列は値ではなく参照によって渡されます。1
か所でのみ使用する場合は、インラインを使用してください。複数の場所で呼び出される場合は、インライン化を検討してください。ただし、保守性には注意し、
使用する関数の複雑さを理解してください。たとえば、similar_text() は O(N^3) です。これは、文字列の長さが 2 倍になり、処理時間が 8 倍になることを意味します。パフォーマンスを向上させるために「戻り参照」を使用しないでください
。自動的に最適化します。
call_user_func_array() や eval() を使用する代わりに、通常の方法で関数を呼び出します。
11. オブジェクト指向の構造
PHP のオブジェクト指向の性質は、パフォーマンスに影響を与える可能性があります。次のヒントは、この影響を最小限に抑えるのに役立ちます。
- すべてが OO である必要はなく、パフォーマンス上のペナルティが利点を上回る可能性があります。
- オブジェクトの作成が遅くなる
- 可能な限り、オブジェクトの代わりに配列を使用してください
- メソッドを静的にできる場合は、静的に宣言します。
- 関数呼び出しは派生クラスのメソッド呼び出しよりも高速であり、派生クラスのメソッド呼び出しは基本クラスの呼び出しよりも高速です
- 最も一般的に使用されるコードを基本クラスから派生クラスにコピーすることを検討しますが、メンテナンスの落とし穴に注意してください
- ネイティブのゲッターとセッターは避けてください。必要がなく、プロパティがパブリックである場合は削除します。
- 複雑な PHP クラスを作成する場合は、シングルトン パターンの使用を検討してください。
12. セッションの処理
セッションの作成には多くの利点がありますが、場合によっては不必要なパフォーマンスのオーバーヘッドが発生します。次のヒントは、パフォーマンスのオーバーヘッドを最小限に抑えるのに役立ちます。
- auto_start を使用しないでください
- use_trans_sid を有効にしないでください
- session_cache_limited を private_no_expire に設定します
- 仮想ホスト (vhost) 内の各ユーザーに独自のディレクトリを割り当てます。
- ファイルベースのセッション処理の代わりにメモリベースのセッション処理を使用する
13. 型キャスト
あるタイプから別のタイプへの変換にはコストが必要です
14. 圧縮
送信前にテキストとデータを圧縮します。
- コードの先頭で ob_start() を使用します。
- ダウンロードを高速化するには ob_gzhandler() を使用しますが、CPU オーバーヘッドに注意してください
- Apache の mod_gzip モジュールは、
15. エラー処理
エラー処理はパフォーマンスに影響します。私たちにできることは次のとおりです。
- エラー ログを記録します。エラー レポートを抑制するために「@」を使用しないでください。抑制するとパフォーマンスに影響します。
- エラーログを確認するだけではなく、警告ログにも対処する必要があります
16. 宣言、定義、および範囲
変数、配列、またはオブジェクトを作成すると、パフォーマンスに影響します。
- グローバル変数/オブジェクトを宣言して使用する方が、ローカル変数/オブジェクトよりも速いという人もいますし、反対する人もいます。テストして決めてください。
- すべての変数は使用する前に宣言し、未使用の変数は宣言しないでください。
- ループ内では可能な限り a[] を使用し、 a[] を避けてください。a [ ] 、 a=array(…)
17. メモリリーク
メモリが割り当てられているのに解放されていない場合、これは間違いなく問題です。
- リソースの解放を主張し、組み込み/自動ガベージ コレクションには頼らない
- 使用後の変数、特にリソース クラスや大きな配列型の設定を解除 (設定解除) してみてください。
- 使用後はデータベース接続を閉じる
- ob_start() を使用するたびに、ob_end_flush() または ob_end_clean() を思い出してください。
18. 車輪を再発明しないでください (車輪を再発明しないでください)
他の人がすでに解決している問題の解決になぜ時間を費やす必要があるのでしょうか?
- PHP、その機能、拡張機能について学びましょう。知らないと、すぐに使える一部の機能を利用できない場合があります。
- 組み込みの配列関数と文字列関数を使用すると、間違いなく最高のパフォーマンスが得られます。
- 先人が発明した車輪があなたの環境で最高のエネルギー吸収を意味するわけではありません、もっとテストしてください
19. コードの最適化
- オペコードオプティマイザーを使用する
- 解釈して実行する場合は、ソースコードを簡略化してください
20、使用RAM(Using RAM Instead of DASD)
RAM は、disk よりもはるかに高速であり、RAM を使用するとパフォーマンスが向上する可能性があります。
- ファイルを Ramdisk に移動する
- ファイルベースのセッション処理の代わりにメモリベースのセッション処理を使用する
21. サービスの使用 (SQL など)
SQL はリレーショナル データベースにアクセスするためによく使用されますが、PHP コードはさまざまなサービスにアクセスできます。以下に留意すべきアクセス サービスをいくつか示します。
- サーバーに何度も東に行くように要求しないでください。メモ化を使用して最初の結果をキャッシュし、アクセス後は直接キャッシュに移動します。
- SQL では、mysql_fetch_array() の代わりに mysql_fetch_assoc() を使用して、結果セット内の整数インデックスを減らします。インデックス番号ではなくフィールド名を使用して結果セットにアクセスします。
- Oracle データベースの場合、使用可能なメモリが十分でない場合は、oci8.default_prefetch を増やします。oci8.statement_cache_size をアプリケーション内のステートメントの数に設定します
- 結果セットが処理のために別のレイヤーに送信される場合を除き、mysqli_fetch_all() の代わりに mysqli_fetch_array() を使用してください。
22. インストールと構成
PHP をインストールして構成するときは、パフォーマンスを考慮してください。
- メモリを追加する
- 競合するアプリやサービスを削除する
- 必要な拡張機能のみをコンパイルする
- PHP を静的に APACHE にコンパイルする
- すべてのコンパイラの最適化を有効にするには、-O3 CFLAGS を使用します。
- 必要なモジュールのみをインストールする
- 最新のマイナー バージョンにアップグレードします。メインボードのアップグレード。最初のバグが修正されるまで待ちます。もちろん、あまり長く待ちすぎないでください。
- マルチCPU環境用に構成する
- -enable-inline-optimization を使用する
- session.save_handler=mm を設定し、-with-mmto でコンパイルし、共有メモリを使用します。
- RAMディスクを使用する
- register_global と magic_quotes_* をオフにする
- 閉じるexpose_php
- 使用する必要がない限り、always_populate_raw_post_data を無効にします
- 非コマンドラインモードで register_argc_argv を閉じてください。
- PHP は .php ファイル内でのみ使用してください
- max_execution_time、max_input_time、memory_limit、output_buffering のパラメーターを最適化します。
- ファイル/ディレクトリのアクセス速度を向上させるには、Apache 構成ファイルのallowoverride を none に設定します。
- -march、-mcpu、-msse、-mmmx、および -mfpmath=sseto による CPU の最適化
- libmysql、mysqli 拡張機能、および PDO MYSQL ドライバーを MySQL ネイティブ ドライバー (mysqlnd) に置き換えます。
- register_globals、register_long_arrays、register_argc_argv を無効にし、auto_globals_jit を有効にします。
23. その他
分類するのが難しいトリックもいくつかあります。
- include()、require() を使用し、include_once() と require_once() を避ける
- include()/require() で絶対パスを使用する
- 静的 HTML は PHP によって生成された HTML よりも高速です
- 正規表現の代わりに ctype_alnum、ctype_alpha、および ctype_digital を使用します
- 単純なサーブレットまたは CGI を使用する
- 本番環境でコードを使用する場合は、可能な限りログを記録する
- 出力バッファリングを使用する
- 比較の代わりにisset( a ) を使用してください。 a) の代わりに比較してくださいa ) a==nullを比較する代わりに、 isnul の代わりに === nullを使用してくださいある===Isの代わりにnull _んウル(ア)
- スクリプトの実行開始時間が必要です。time() を使用する代わりに $_SERVER['REQUEST_TIME'] を直接読んでください。
- print の代わりに echo を使用する
- ポストインクリメント (i++) の代わりにプレインクリメント (++i) を使用すると、ほとんどのコンパイラが最適化されますが、最適化されない場合はそのままにしてください。
- XML を処理するには、DOM または SAX の代わりに正規表現を使用します。
- HASH アルゴリズム: md4、md5、crc32、crc32b、sha1 は他のハッシュ速度よりも高速です
- spl_autoload_extensions を使用する場合は、最もよく使用されるファイル拡張子 -> 最も一般的に使用されないファイル拡張子の順序に従い、まったく使用されないファイル拡張子を除外するようにしてください。
- fsockopen または fopen を使用する場合は、ドメイン名の代わりに IP アドレスを使用します。ドメイン名が 1 つしかない場合は、gethostbyname() を使用して IP アドレスを取得します。cURL を使用すると高速になります。
- 可能な限り、動的コンテンツを静的コンテンツに置き換えてください。