PHP
パフォーマンス
サーチ…
XHProfによるプロファイリング
XHProfは、もともとFacebookによって書かれたPHPプロファイラで、XDebugに代わる軽量の代替ツールです。
xhprof
PHPモジュールをインストールした後、PHPコードからプロファイリングを有効/無効にすることができます:
xhprof_enable();
doSlowOperation();
$profile_data = xhprof_disable();
返される配列には、 doSlowOperation()
内でアクセスされた各関数の呼び出し回数、CPU時間、およびメモリ使用量に関するデータが格納されます。
xhprof_sample_enable()
/ xhprof_sample_disable()
は、より軽量なオプションとして使用することができます。これは、ほんの一部の要求(および別の形式)のプロファイリング情報を記録するだけです。
XHProfには、データを表示するヘルパー関数(ほとんどの場合はドキュメント化されていない)があります( 例を参照 )。また、他のツールを使って可視化することもできます(platform.shブログに例があります )。
メモリ使用量
PHPのランタイムメモリの制限は、INIディレクティブmemory_limit
によって設定されます。この設定では、PHPを単独で実行するとメモリを使い切ってしまい、他のスクリプトやシステムソフトウェアを使い果たすことがありません。メモリ制限はデフォルトで128Mで、 php.ini
ファイルまたは実行時に変更できます。これは無制限に設定することができますが、これは一般的に悪い習慣とみなされます。
実行時に使用される正確なメモリ使用量は、 memory_get_usage()
呼び出すことによって判断できます。現在実行中のスクリプトに割り当てられているメモリのバイト数を返します。 PHP 5.2では、PHPが積極的に使用しているメモリとは対照的に、割り当てられたシステムメモリ全体を取得するためのオプションのブール型パラメータが1つあります。
<?php
echo memory_get_usage() . "\n";
// Outputs 350688 (or similar, depending on system and PHP version)
// Let's use up some RAM
$array = array_fill(0, 1000, 'abc');
echo memory_get_usage() . "\n";
// Outputs 387704
// Remove the array from memory
unset($array);
echo memory_get_usage() . "\n";
// Outputs 350784
これで、 memory_get_usage
は実行時のメモリ使用量を示します。この関数への呼び出しの間に、メモリ内の他のものを割り当てたり割り当てを解除することができます。使用されているメモリの最大量を特定のポイントまで取得するには、 memory_get_peak_usage()
呼び出します。
<?php
echo memory_get_peak_usage() . "\n";
// 385688
$array = array_fill(0, 1000, 'abc');
echo memory_get_peak_usage() . "\n";
// 422736
unset($array);
echo memory_get_peak_usage() . "\n";
// 422776
値が上がるか、または一定に留まることに注意してください。
Xdebugによるプロファイリング
Xdebugと呼ばれるPHPの拡張機能は、 PHPアプリケーションのプロファイリングやランタイムのデバッグを支援するために利用できます。プロファイラを実行すると、出力は "cachegrind"というバイナリ形式でファイルに書き込まれます。これらのファイルを分析するために、各プラットフォームでアプリケーションを利用できます。
プロファイリングを有効にするには、拡張機能をインストールし、php.iniの設定を調整します。この例では、オプションでリクエストパラメータに基づいてプロファイルを実行します。これにより、設定を静的に保ち、必要に応じてプロファイラをオンにすることができます。
// Set to 1 to turn it on for every request
xdebug.profiler_enable = 0
// Let's use a GET/POST parameter to turn on the profiler
xdebug.profiler_enable_trigger = 1
// The GET/POST value we will pass; empty for any value
xdebug.profiler_enable_trigger_value = ""
// Output cachegrind files to /tmp so our system cleans them up later
xdebug.profiler_output_dir = "/tmp"
xdebug.profiler_output_name = "cachegrind.out.%p"
次に、Webクライアントを使用して、プロファイルするアプリケーションのURLをリクエストします。
http://example.com/article/1?XDEBUG_PROFILE=1
ページが処理されるとき、それは同じ名前のファイルに書き込みます
/tmp/cachegrind.out.12345
実行されたPHPリクエスト/プロセスごとに1つのファイルが書き込まれることに注意してください。したがって、たとえば、フォーム・ポストを分析する場合は、HTMLフォームを表示するGET要求用のプロファイルが1つ作成されます。 XDEBUG_PROFILEパラメーターは、フォームを処理する2番目の要求を分析するために、後続のPOST要求に渡す必要があります。したがって、プロファイリング時に、フォームを直接POSTするためにcurlを実行する方が簡単な場合があります。
書かれたプロファイルキャッシュは、KCachegrindなどのアプリケーションで読み取ることができます。
これにより、以下を含む情報が表示されます。
- 実行される関数
- 呼び出し時間、それ自身と後続の関数呼び出しを含む
- 各関数が呼び出された回数
- コールグラフ
- ソースコードへのリンク
明らかに、パフォーマンスチューニングは各アプリケーションのユースケースに固有のものです。一般的にそれを探すのは良いことです:
- あなたが見たくない同じ機能への呼び出しを繰り返す。データを処理し照会する関数の場合、これらは、アプリケーションがキャッシュする可能性があります。
- 低速実行機能アプリケーションはほとんどの時間をどこに費やしていますか?パフォーマンスチューニングの最善の利益は、最も時間を費やすアプリケーションの部分に焦点を当てています。
注意 :Xdebug、特にそのプロファイリング機能は、リソースを大量に消費し、PHPの実行を遅くします。実動サーバー環境でこれらを実行しないことをお勧めします。