はじめに
Crystalでどのメソッドがどのメソッドから呼ばれているか知りたいことなどありませんか?
Rubyは動的言語でREPLを使った内観に優れていますが、Crystalではオブジェクトの内観が難しいと感じることがあります。
そういった難しさに対処するために、静的言語向けの解析ツールに慣れていきたいですね。
今日はValgrindを使ってコールグラフを書いてみます。人生でValgrindを使うのは3回目ぐらいなので記事がテキトーなのはご容赦ください。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fvalgrind.org%2Fimages%2Fst-george-dragon.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=478e7775834ebc8355382c33a7fdb057)
ValgrindはLinux用のデバッグツールで、その名前は北欧神話におけるヴァルハラ1への入り口の名に由来しています。この記事は下の記事を参考に書かれました。
とにかくカッコよくて面白い KCachegrind の画面。crystalの文字が見えるだろうか。
用意したコード
それでは今回利用する簡単なコードを用意しました。
piyo0
-> piyo1
-> piyo2
-> piyo3
-> piyo4
-> piyo5
-> piyo6
-> piyo7
-> piyo8
-> piyo9
-> piyo10
の順番でメソッドが呼ばれていきます。
class Tori
def initialize(@x = 0)
end
def piyo
@x = 0
piyo1
end
def piyo1
@x = 1
piyo2
end
def piyo2
@x = 2
piyo3
end
def piyo3
@x = 3
piyo4
end
def piyo4
@x = 4
piyo5
end
def piyo5
@x = 5
piyo6
end
def piyo6
@x = 6
piyo7
end
def piyo7
@x = 7
piyo8
end
def piyo8
@x = 8
piyo9
end
def piyo9
@x = 9
piyo10
end
def piyo10
@x = 10
end
end
t = Tori.new
# `piyo0` -> `piyo1` -> `piyo2` -> `piyo3` -> `piyo4` -> `piyo5` -> `piyo6` -> `piyo7` -> `piyo8` -> `piyo9` -> `piyo10`
t.piyo
ではビルドしてみましょう。今回はパフォーマンスを調べたいわけではないのでデバッグビルドしておきます。
crystal build --debug piyo.cr
Valgrindで解析します。
valgrind --tool=callgrind ./piyo # = は必須
KCachegrinbdを起動します。
kcachegrind callgrind.out.9792 # 番号はCallgrindを実行したプロセスのID
こんな感じのかっこいい画面が出てくると思います。
すでに、この時点で画面がめちゃくちゃ面白いのです。面白いのですが、勉強中でわかっていない点が多いのでスルーします。さて、piyo
系のメソッドは実質何もやっていないメソッドなので実行時間も極端に短く、検索して見つけた方が早いと思います。
いたいた。
これで、piyoを選択すると、ジャーン!!
めっちゃわかりやすい!!
piyo系のメソッドが10まで順番に呼ばれているのを見ることができます。
非常に面白いですね。
今日ははじめてなのでこのぐらいにしておきます。
ValgrindとKCachegrindやばいですね。こ、これが北欧神話か……
この記事は以上です。
Valgrindの仕組み
英語版のWikipediaのValgrindの項目を日本語に翻訳したが、かなりメチャクチャなツールだということがわかる。作者の Julian Seward さんすごすぎ……。
Valgrindは本質的に、動的再コンパイルを含むジャストインタイムコンパイル技術を使用する仮想マシンです。元のプログラムから直接ホストプロセッサ上で実行されることはありません。代わりに、Valgrindは最初にプログラムを「中間表現(IR)」と呼ばれる一時的でより単純な形式に変換します。これはプロセッサに依存しない、静的な単一割り当て形式に基づく形式です。変換後、ツール(後述)はIR上で任意の変換を行うことができ、その後ValgrindはIRを再びマシンコードに変換してホストプロセッサが実行できるようにします。Valgrindはバイナリコードを再コンパイルして、同じアーキテクチャのホストおよびターゲット(またはシミュレートされた)CPU上で実行します。また、Valgrind内で実行中のターゲットプログラムをデバッグするためのGDBスタブを含み、「モニターコマンド」を使用してさまざまな情報についてValgrindツールに問い合わせることができます。
ヴァルハラとはなにか
-
北欧神話における主神オーディンの宮殿。ヴァルハラはグラズヘイムにあり、ワルキューレによって選別された戦士の魂(エインヘリャル)が集められる。レーラズ(英語版)(ユグドラシルの1本)の影が落ちるこの宮殿には、540の扉、槍の壁、楯の屋根、鎧に覆われた長椅子があり[1]、狼と鷲がうろついているという。これは、戦場の暗喩である。館の中では戦と饗宴が行われ、ラグナロクに備える。また、この館には雄鶏のグリンカムビ(黄金の鶏冠)が住んでいるとされている。 Wikipediaより