Perlの代替として(3)

実用的なプログラムを作ってみる

これくらいわかっていれば実用的なプログラムが作れるのではないか。
そう思って次のようなものを作ってみた。


プログラムを実行したときに、ある部分の実行時間を知りたいとする。
そこで、C/C++のコードのところどころに、


fprintf(stderr, "a %d\n", timeGetTime());

というコードを埋めておく。
timeGetTimeはWindowsの起動からの経過時間をミリ秒で返す。
頭の'a'は場所によって変えておく。
そうして実行すると、次のようなログが得られる。


a 100000000
b 100000111
c 100000132
a 100000137
b 100000230
hoehoe
c 100000250

このログを次のようなPerlのプログラムにかける。


my %totalTime;
my $prevTime = -1;
my $prevWord;

while(<>) {
my ($word, $now);
if(($word, $now) = /(\w+) (\d+)/) {
if($prevTime >= 0) {
my $rangeName = $prevWord . " -> " . $word;
$totalTime{$rangeName} += $now - $prevTime;
}
$prevWord = $word;
$prevTime = $now;
}
}

for my $range(sort keys %totalTime) {
printf "%s %.3f\n", $range, $totalTime{$range} / 1000;
}

そうすると、次のような出力になる。


a -> b 0.204
b -> c 0.041
c -> a 0.005

これは、aからbの範囲の実行時間がトータルで0.204秒、
などということである。


これをD言語で書いてみる。


文字列の注意点

最初にハマったのは次の点。


char [] str = "abc";
char [] str2, str3;
str2 = str ~ str; // 文字列の結合
str3 = str2;
str2[5] = 'd';
dout.writeLine(str3); // abcabd

str3 = str2 は単にアドレスを代入しているだけ。
文字列のコピーではない。
コピーは次のように行う。


str3 = str2.dup; // コピー
str2[5] = 'd';
dout.writeLine(str3); // abcabc

あまり美しくない気がする。
strcpyよりはずっとマシだけれど。
STLのstringですら、コピーになるのに。


文字列の結合

前回出てきたように、文字列の結合には、+ではなく、~を使う。


char [] str = "abc";
auto str2 = str ~ str; // abcabc

配列の結合も同じ演算子を使う。
(文字列は配列だから当然だが)