- blogs:
- cles::blog

Advanced PHP debugger

犯人はNP_BlackListで、PHPスクリプトの性能が悪い現象を解析するためにPHP用のプロファイラを使ったので忘れないうちにメモを書いておきます。
† APD (Advanced PHP debugger)
今回はプロファイラとしてしか使っていませんが、APDのドキュメントやPECLのサマリにはA full-featured engine-level profiler/debuggerと書いてあるので、デバッガとしての機能もいろいろとあるようです。
† セットアップ
ダウンロードはPECLのAPDから可能です。PHP 4.4.0で最新版のAPD 1.0.1を使おうとしたところ、PHPが古いと怒られてしまったので、今回は0.9.2をインストールしました。あとで分かったことですが、1.0.1と0.9.2はリリース日が同じなのでおそらく1.0.x系がPHP5用で、0.9.x系がPHP4用のような気がします。
ビルド・インストール手順はこんな感じ。
プログラムのトレース情報を人が読めるようにするため「pprofp」というツールがディレクトリに入っているので、必要に応じて/usr/local/binとかにコピーしておいた方がいいでしょう。僕はこのツールが見つけられなくて後ではまったので。
† PHPへの組み込み
APDはzendモジュールなので、php.iniの書き換えてPHP起動時にモジュールが読み込まれるようにする必要があります。ということでphp.iniに以下の記述を追加。
php.ini(追加分のみ)
apd.soがある場所は環境によって違うので、APDインストール時にどこにapd.soがインストールされたのかは確認しておく必要があります。また、"apd.dumpdir"はトレース情報を格納するためのディレクトリなので必ず指定しておきましょう。これらの設定が済んだらApacheを再起動します。その後phpinfo()でモジュールがロードされているか確認しておくと間違いがないです。
† トレース情報を取得してみる
準備ができたのでトレース情報を取得してみます。今回のトレース対象はNucleusなので、Nucleusの設定ファイルであるconfig.phpの上部にトレースを開始するための関数を記述しました。
config.php (追加分のみ)
この状態でNucleusのサイトを表示すると、"apd.dumpdir"で指定したディレクトリに「prof.(プロセスID).(連番)」のようなトレース情報が入ったファイルができます。
公開しているウェブアプリのトレース情報を取得する場合には、必要な分のファイルが取得できたことが確認できたら、プログラム中の"apd_set_pprof_trace();"はすぐに削除した方がよいです。僕の場合、ちょうどYahooのロボットがやってきていた時間帯だったので、気がついたらトレースファイルが数百個できてしまっていました。
† 解析する
トレース情報はこんな感じで出力されます。
cat pprof.27289.6 (先頭だけ)
テキストなので読もうと思えば読めなくもないのですが、読みやすい形式に変換することが賢明です。これはAPD付属の"pprofp"というコマンドで行うことができます。
# pprofp -R /tmp/pprof.27289.6
あとは表示されたこのデータを読むだけです。まずこのデータの2カラム目の数値が最大の部分を探します。この例の場合には、fopen()の0.53というのが最大値になっているのが分かると思います。この例の場合、全体の実行時間("Total Elapsed Time")が1.08秒なので、この部分だけで全体の半分近くの時間を消費していることが分かります。
このように性能を劣化させている原因がわかったら、その部分がプログラム中のどこであるのかを確定していきます。たいていの場合原因となっている部分の直前の行がその原因を含んでいる部分になります*1。この例の場合には"pbl_updateblacklist"が性能を劣化させる部分であるということが分かります。
この方法で部位が特定できない場合には"pprofp -t"を使って、call treeを出力させてその中を検索していく方法もあります。
# pprofp -t /tmp/pprof.27289.6 (先頭だけ)
今回はひとつの処理が遅かっただけなので、すぐに性能劣化の原因が分かったのですが、場合によっては、そんなに遅くない処理をループなのでものすごい回数呼び出したりしている場合もあるので、その関数の実行回数であるCallsの部分に注目することも必要になってくると思います。
- *1: 出力がスタックトレースの順序になっているから
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/1093
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。
OpenID を使ってログインすることができます。
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(112029)
3 . 年次の人間ドックへ(111520)
4 . 2023 年分の確定申告完了!(1つめ)(111116)
5 . 三菱鉛筆がラミーを買収(111003)