読者です 読者をやめる 読者になる 読者になる

in the mythosil

Rhythm & Biology.

perlの実行時間計測とInline::Cのすごさ

研究として数値計算をやることが多いのですが、やはり実行時間が気になってしまうものです。
perlに限らず、スクリプト言語はやはり速度面でのネックがありますが、まずは実行時間を計測してどれぐらい遅いのかを知りたいと思いました。

簡単な数値積分(Euler法)をまずperlで書いてみます。

# ode.pl
use Time::HiRes qw/gettimeofday tv_interval/;
my $start = [gettimeofday];
my ($x, $y) = (1.0, 0.0);
for (my $t = 0.0; $t < 10000.0; $t += 0.01) {
  my $d = $x * 0.00001;
  $x -= $d;
  $y += $d;
}
my $end = [gettimeofday];
print "TIME(Perl): ", tv_interval($start, $end), "\n";

Time::HiResモジュールを使って実行時間を計測しています。unixのtimeコマンドを使っても良かったのですが、今回はperlの勉強ということで。
さて、これを実行すると、

TIME(Perl): 0.557612

という結果になります。今度は、Inline::Cを使って高速化を狙ってみます。

# ode_c.pl
use Time::HiRes qw/gettimeofday tv_interval/;
use Inline C;
my $start = [gettimeofday];
ode();
my $end = [gettimeofday];
print "TIME(C): ", tv_interval($start, $end), "\n";
__END__
__C__
void ode() {
  double x = 1.0, y = 0.0, t;
  for (t = 0.0; t < 10000.0; t += 0.01) {
    double d = x * 0.00001;
    x -= d;
    y += d;
  }
}

Inline::Cを使った場合、最初の一回はコンパイルに時間がかかります。念のため、こちらはtimeコマンドでの計測も行ってみます。

% time perl ode_c.pl
TIME(C): 0.001809
perl ode_c.pl  0.85s user 0.27s system 90% cpu 1.235 total
% time perl ode_c.pl
TIME(C): 0.001769
perl ode_c.pl  0.04s user 0.01s system 77% cpu 0.060 total

コンパイルにはそれなりの時間がかかっています。しかし、二回目以降はpure perlよりも圧倒的に速いのが分かります。Inline::Cすさまじき。

なんだか色々と怪しい測定法な気もしますが、数値計算のような部分はInline::Cで書くのがベストですね。ただ、use strictをつけると怒られるのが気になります。