dmdにはWindowsもしくはx86系のアーキテクチャの場合は -profile オプションで実行したプログラムのプロファイルを取得することができます。
dmdのmanを見ると、
-profile Profile the runtime performance of the generated code
こういう風に確認できます。
実際に適当なプログラムで計測ととってみます。結果は trace.log
というファイルに書き込まれます。
全部貼ると長いので一部だけとってくると、
... ======== Timer Is 3579545 Ticks/Sec, Times are in Microsecs ======== Num Tree Func Per Calls Time Time Call 12 46493 46493 3874 _D3std5stdio4File17LockingTextWriter10__T3putTaZ3putMFNfaZ12trustedFPUTCFNbNiNeiPS4core4stdc5stdio8_IO_FILEZi 60 3872 3872 64 @safe void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[]) 1 91349 3206 3206 _Dmain 12 76720 3079 256 @safe void std.stdio.File.write!(cssparser.tokenizer.Token, char).write(cssparser.tokenizer.Token, char) 12 26863 3075 256 @safe uint std.format.formattedWrite!(std.stdio.File.LockingTextWriter, char, cssparser.tokenizer.Token).formattedWrite(std.stdio.File.LockingTextWriter, const(char[]), cssparser.tokenizer.Token) 13 7578 2778 213 cssparser.tokenizer.Token cssparser.tokenizer.Tokenizer.nextToken() 12 11926 2655 221 @safe void std.format.formatElement!(std.stdio.File.LockingTextWriter, immutable(char)[], char).formatElement(std.stdio.File.LockingTextWriter, immutable(char)[], ref std.format.FormatSpec!(char).FormatSpec) 24 3147 2450 102 @safe bool std.format.FormatSpec!(char).FormatSpec.writeUpToNextSpec!(std.stdio.File.LockingTextWriter).writeUpToNextSpec(std.stdio.File.LockingTextWriter) 16 2410 2410 150 pure nothrow ref @trusted std.array.Appender!(immutable(char)[]).Appender std.array.Appender!(immutable(char)[]).Appender.__ctor(immutable(char)[]) 17 3569 2199 129 pure @safe void std.format.formatChar!(std.array.Appender!(immutable(char)[]).Appender).formatChar(std.array.Appender!(immutable(char)[]).Appender, const(dchar), const(char)) 41 2054 1998 48 pure nothrow @trusted void std.array.Appender!(immutable(char)[]).Appender.ensureAddable(ulong) 12 20264 1691 140 @safe void std.format.formatValue!(std.stdio.File.LockingTextWriter, ...
だいたいこんな感じの出力結果になります。
これの実体はdruntimeの rt.trace.QueryPerformanceCounter
というあたりなのですが、このQueryPerformanceCounterというのは同名のWin32 APIが元になっています。
実際Windowsの場合はこのQueryPerformanceCounterが使われていますが、Linux x86系ではWin32 APIはもちろん使うことができません。
なのでどうしているかというと、rdtsc命令を使ってタイプスタンプ値を取得しています。
ちょうど wiki.dlang.org にも rdtscを使った時間計測方法 がのっています。(どうでもいいですがちょっと情報が古いですね、、今はstd.perfではなくrt.traceにありますし-gtオプションもdeprecated扱いです。)
ちなみに rdtsc で取得できるタイムスタンプ値はコア毎に違っているため、コンテキストスイッチが発生すると正しくない値が取得される場合があるので注意が必要です。