DTrace を使用することで、システムやアプリケーションに手を加えることなく、それらをトレースすることができます。MacRuby はメソッドの振る舞いをトレースするために、いくつかプローブというものを用意しています。
プローブ名 | 実行タイミング | arg0 | arg1 | arg2 | arg3 |
method-entry | メソッド呼出開始 | クラス名 | メソッド名 | ソースファイル名 | 行番号 |
method-return | メソッド呼出終了 | クラス名 | メソッド名 | ソースファイル名 | 行番号 |
raise | 例外発生時 | クラス名 | ソースファイル名 | 行番号 | - |
これらを使用することで、メソッドが呼び出された回数や実行時間を簡単に計測できます。
以下は String クラスのメソッドの合計実行時間を計測するための DTrace スクリプトです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| #!/usr/sbin/dtrace -s
#pragma D option quiet
macruby$target:::method-entry
/ copyinstr(arg0) == "String" / /* invokes only String methods */
{
self->starttime = walltimestamp / 1000;
}
macruby$target:::method-return
/ copyinstr(arg0) == "String" / /* invokes only String methods */
{
@invoked_time[copyinstr(arg0), copyinstr(arg1)] = sum((walltimestamp / 1000) - self->starttime);
}
END
{
printf("\n");
printf("%-10s %-15s %s\n", "CLASS", "METHOD", "TOTAL TIME µsec");
printf("--------------------------------------------------------------------------------\n");
printa("%-10s %-15s %@d\n", @invoked_time);
}
|
実行時間を計測する Ruby のプログラムを用意します。
1
2
3
4
5
| # test.rb
1000.times do
str = "abc\n" * 1000
str.split("\n")
end
|
これらを実行すると以下のような結果となります。
1
2
3
4
5
6
| $ sudo dtrace -qs time.d -c "macruby test.rb"
CLASS METHOD TOTAL TIME µsec
--------------------------------------------------------------------------------
String *: 6578
String split: 1275979
|
DTrace については、以下のサイトなどが有益です。