ベンチマーク

昨日の続きです。単純な加算を5000万回繰り返してどのくらい時間がかかるか見てみます。

bench_cpp.cpp(g++ -O3 -o bench_cpp.cgi bench_cpp.cpp)

ネイティブだと0.04秒くらいで終わってしまいました。さすがに早いです。

#include <stdio.h>
 
int main() {
    printf("Content-type: text/plain;charset=x-euc-jp\n\n");

    printf("BenchMark Started\n");
    {
        int a = 0;
        for (int i = 0; i < 10000; i++) {
            for (int j = 0; j < 5000; j++) {
                a++;
            }
        }
        printf("a=%d\n", a);
    }
    printf("BenchMark Ended\n");
}

bench_perl.cgi

こっちは10秒以上かかってしまいました。ざっとC++の230倍ほどかかりました。余りにも単純なループなので最適化されてもよさそうなもんですけどね・・。ちなみにfor文の代わりにforeach文を使うと数秒短くなります。

#!/usr/bin/perl

use strict;

{
    printf("Content-type: text/plain;charset=x-euc-jp\n\n");

    printf("BenchMark Started\n");
    {
        my $a = 0;
        for (my $i = 0; $i < 10000; $i++) {
            for (my $j = 0; $j < 5000; $j++) {
                $a++;
            }
        }
        printf("a=%d\n", $a);
    }
    printf("BenchMark Ended\n");
}

bench_inline.cgi

反則技のインラインC++です。こんな超絶技巧ができる言語はそうそうないと思います。これだと0.06秒くらい。C++より若干遅いようですが、Perlとは比べ物になりません。

#!/usr/bin/perl

use Inline CPP;
use Inline (Config => 
            DIRECTORY => './_Inline',
            );
use strict;

{
    start();
}

__END__
__CPP__
#include <stdio.h>

int start() {
    printf("Content-type: text/plain;charset=x-euc-jp\n\n");

    printf("BenchMark Started\n");
    {
        int a = 0;
        for (int i = 0; i < 10000; i++) {
            for (int j = 0; j < 5000; j++) {
                a++;
            }
        }
        printf("a=%d\n", a);
    }
    printf("BenchMark Ended\n");
}

まとめ

速度的なボトルネックになっているところをCやC++に書き換えれば、場合によっては実行速度が数百倍速くなるということがわかりました。インラインC++を使う場合初回アクセス時とソースコードを書き換えたときはコンパイルされるため若干遅めです。まぁJSPの初回アクセスと似たようなものでしょう。