Devel::NYTProfからコールグラフを生成する

ソースコードを追っかけるときにコールグラフが分かっていると便利です。
時間が十分あるのであれば、自分でじっくり追いかけるというのもありかと
思うんですけど、事前にコールフローが分かっている方が、確実に追いかけることができます。


以前作成した
Google URL Shortener APIを使う - syohex’s diary
コールグラフを見てみようと思います。

準備

KCachegrindをインストールします。Qtが使われているので、Ubuntuなんかの
GNOMEが使用されているディストリだと大量のライブラリが入りますけど、
そこは我慢ということでインストールしてください。

  % sudo aptitude install kcachegrind

当たり前ですが、Devel::NYTProfもインストールします。

  % cpanm Devel::NYTProf

プロファイル結果の出力

Devel::NYTProfを使って、プログラムを実行して、プロファイリング結果を
出力します。

  % perl -d:NYTProf googl.pl http://d.hatena.ne.jp/syohex/

カレントディレクトリに nytprof.outが生成されました。

Callgrind形式のファイルの出力

  % nytprofcg --file=nytprof.out --out=nytprof.callgrind

nytprof.callgrindというファイルが生成されます。

KCachegrind

先ほど出力された nytprof.callgrindを KCachegrindで開きます。

  % kcachegrind nytprof.callgrind

するとアプリが起動し、以下のような画面になります。

送信者 blog

大まかには左半分が関数リストで、右半分がそれぞれの関数の情報に
なります。左の関数リストからコールフローがみたい関数を選びます。
全体をみたいのであれば、mainパッケージのものを選択するのがいいかと
思います。関数を選んだら右下にある "Call Graph"というタブを選択
します。すると以下のようにコールグラフが見えます。

送信者 blog


このコールグラフは画像としてエクスポートできます。誰かに見せたい
なんていう場合は、データファイル送るよりかは画像データを送った方が
いいでしょう。理解がない人に対してであれば、特に。

エクスポートするにはコールグラフの部分で右クリックを押して、
"Export Graph" => "As image"と選択します。画像の形式はよく
わからなかったのですが、.pngとして出力すれば pngファイルとして
見れましたので、とりあえずはそうするのが無難かと思います。
エクスポートした図は以下のようになります。

送信者 blog

PNGファイルとして見ることができました。

画像の調整

エクスポートした図はコードにもよりますが、結構大きいです。もうちょっと
小さくても十分見れるので、必要があれば小さくしましょう。convertコマンドを
使えば簡単に画像サイズを調整できます。convertコマンドは imagemagick
パッケージに含まれているので適宜インストールしてください。

  % convert -geometry "80%" sample.png sample_small.png

パーセンテージの部分を変えることで任意のサイズにできます。
あまり小さいと文字が小さくなりすぎて読めなくなるので気をつけてください。

関数に含まれない部分

どの関数にも属していない部分は分断されてしまうようです。ここでは
main::BEGIN@7, main::BEGIN@10みたいな感じになってしまいました。
この場合それぞれは独立しているため、完全なコールフローにはなり
ませんでした。あまり気にするところではないですが、一つのグラフに
したいのであれば、mainって関数を作るのがいいかと思います。

まとめ

Devel::NYTProfからコールグラフを生成する方法を生成する方法を
示しました。Devel::NYTProfというとボトルネック調査のために
nytprofhtmlが使用されることが多いかと思いますが、nytprofcgも
便利だということがわかりました。


きちんと視覚化されてるっていうのは、理解の役にも立ちますので
(自分で書くのが一番いいんだろうけど)、有効に活用できればいいかなと思います。


nytprofhtmlを使った場合でも、dotファイルがそれぞれ生成され、
dotコマンドでグラフ化できるんですが、どうも普通に生成しただけ
ではまともなグラフになりませんでした。
具体的には横30000ピクセル、縦 300ピクセルみたいな画像しか生成
できませんでした。