前の関連記事:linuxBean14.04(39)Pythonのパッケージ管理をPyCharmで行う
pycallgraphを使ってPythonのコールグラフを出します。最終的にはLibreOffice5のバンドルPythonからコールグラフをだせるようにします。まずはpycallgraphのインストールと出力されたコールグラフの色の意味について調べました。
pycallgraphとgraphvizのインストール
pycallgraphはPyCharmのsettings→Project:python→Project Interpreterで/usr/bin/python3.3を選択した状態でpycallgraphをインストールします。
linuxBean14.04(39)Pythonのパッケージ管理をPyCharmで行うのpthファイルを設定してあるとインタープリターを/opt/libreofficedev5.0/program/pythonにしたときもpycallgraphがパッケージにでてきます。
次にSynapticパッケージマネージャからgraphvizをインストールします。
これで準備完了です。
Terminalからgraphviz --helpとすると使い方が表示されるはずです。
pycallgraphでコールグラフを出力する
まず手始めにlinuxBean14.04(38)LibreOfficeバンドルPythonにパッケージを追加で使ったsite.pyのコールグラフを見てみます。
pycallgraph graphviz /usr/lib/python3.3/site.py
pq@pq - VirtualBox:~$ pycallgraph graphviz / usr / lib / python3. 3 / site.py sys.path = [ '/home/pq' , '/usr/local/bin' , '/usr/lib/python3.3' , '/usr/lib/python3.3/plat-i386-linux-gnu' , '/usr/lib/python3.3/lib-dynload' , '/home/pq/.local/lib/python3.3/site-packages' , '/usr/lib/python3/dist-packages' , '/usr/local/lib/python3.3/dist-packages' , ] USER_BASE: '/home/pq/.local' (exists) USER_SITE: '/home/pq/.local/lib/python3.3/site-packages' (exists) ENABLE_USER_SITE: True |
pycallgraphの結果はpycallgraphを実行したフォルダにpycallgraph.pngというファイル名で出力されています。
3521x2040ピクセルもある巨大pngファイルです。
ダウンロードして拡大して見ないとよくわからないと思います。
同じファイルをWindowsフォトビューアーで見るとlinuxBeansのイメージビューワより文字が見にくいのはなぜだろうか、、、Windows7ではChromeで開いたほうが綺麗に見えました。
ちなみにlinuxBean14.04のデフォルトイメージビューワGPicViewでは、左のCtrlボタンを押しながらマウスホイールを回すと画像の拡大/縮小ができます。
彩度が高いノードが改善効果がでやすい部分
Customisable colors. You can programatically set the colors based on number of calls, time taken, memory usage, etc.呼び出し回数や占有時間、メモリー消費量を元に色のカスタマイズができると書いてあるのですが、カスタマイズのやり方を書いてある資料を見つけられませんでした。
Python Call Graph — Python Call Graph 1.0.1 documentation
先ほどのコールグラフをよく見てみると、timeの数値が大きい頂点(vertex,node)(以下ノードと呼称)ほど灰色から紫色に近くなっているようです。
ノードを結ぶ矢印(枝、branch,edge)(以下エッジと呼称)は行き先の色と同じになるようです。
(グラフの用語はPython(7)二分木(Binary Tree)の勉強資料を求めて本屋へで購入した教養のコンピュータアルゴリズムのP65によりました。)
エッジに付随する数値はその先のノードを呼び出した回数になっています。
/usr/local/lib/python3.3/dist-packages/pycallgraph/color.pyを読むとr,g,bを何か計算しているようです。
332 333 334 335 336 337 338 339 340 341 342 343 344 |
class Stat( object ): '''Stores a "statistic" value, e.g. "time taken" along with the maximum possible value of the value, which is used to calculate the fraction of 1. The fraction is used for choosing colors. ''' def __init__( self , value, total): self .value = value self .total = total try : self .fraction = value / total except ZeroDivisionError: self .fraction = 0 |
例えば、占有時間の全体に対する割合を算出してその数値(fraction)を色の設定に使っているようです。
32 33 34 35 36 37 38 |
def node_color( self , node): value = float (node.time.fraction * 2 + node.calls.fraction) / 3 return Color.hsv(value / 2 + . 5 , value, 0.9 ) def edge_color( self , edge): value = float (edge.time.fraction * 2 + edge.calls.fraction) / 3 return Color.hsv(value / 2 + . 5 , value, 0.7 ) |
結構複雑ですねえ。RGBではなくてHSVで計算していますし。
RGBとHSVも昔どこかで勉強した記憶がありますがこのブログを検索しても記事は出てきませんでした。
H:色相(Hue)、S:彩度(Saturation)、V:明度(Value) (HSV色空間 - Wikipedia)
中学校の美術の時間で習ったやつです、、、教科書残しておけばよかった、、、
とりあえずノードの色についての計算式を展開してみます。
t:占有時間、c:呼び出し回数
v=13(2t∑t+c∑c)
ノードの色
(H,S,V)=(v+12,v,0.9)
エッジの色
(H,S,V)=(v+12,v,0.7)
占有時間割合に2倍の重みをつけて呼び出し回数割合との加重平均v(0≤v≤1)を得て、色相Hをv+12、彩度Sをv、明度Vを0.9(エッジは0.7)にしています。
エッジの色はノードの色をちょっと暗くしたものとわかります。
色相で1を加えて2で割っているのは色相が一周すると元の色に戻ってしまうから、、、
vが1のときにHは1になってしまいますし、、、でもvが0のときにHは0.5になるのでやっぱりそうかも。(すぐあとでやる彩度を1にしたコールグラフの結果を見ると色相は180度の水色から始まって360度の赤になるようになっているとわかりました。)
Hの違いは色相 - Wikipediaのスケールでわかりますが、彩度の変化が加わるとどっちが数値が大きいのか私には直感的によくわかりません。
彩度 - Wikipediaの色空間の横断面の図に対応させるとまだわかるかも。
彩度を1に決めうちしてやってみました。
鮮やかになりましたが、ノードのラベルが読みにくくなってしまいました。
不思議なことにグラフの形も変わってしまいました。
彩度を戻してやり直してみると少しずつグラフの形が違いました。
やっぱり彩度に変化があったほうがよいですね。
彩度が高いものが着目すべきものということですね。
これらの彩度が低くなるように改善すると処理速度が速くなるので、自分でプログラミングしているときはそこを重点的に改善しないといけないとわかるわけですね。
参考にしたサイト
Python Call Graph — Python Call Graph 1.0.1 documentation
Pythonのコールグラフを出力してくれるpycallgraph。
HSV色空間 - Wikipedia
pycallgraphでは各ノードの占有時間と呼び出し回数を元にノードの色相と彩度を変化させて出力します。
色相 - Wikipedia
色相を変えると色の種類が変わります。
彩度 - Wikipedia
彩度を変えると色の鮮やかさが変わります。
0 件のコメント:
コメントを投稿