osdev-jpでは、OS開発に有用な情報を収集し公開しています

View My GitHub Profile

OpeLa メインページ

Ver.1 と Ver.2 で、生成された機械語の性能を測定しました。測定対象の OpeLa プログラムは次の通り。 ただし、計測当時、Ver.2 コンパイラはまだ関数定義に対応してなかったので、func main() を取り除いたプログラムをコンパイラへの入力とします。

func main() { s:=0; for i:=1;i<10000;i=i+1{ for j:=1;j<200000;j=j+1{ s=s+i*j; } } s; }

出力されたアセンブリ言語プログラムは Gist に載せました。Ver.1 の出力 Ver.2 の出力

Ver.2 はデバッグ情報を大量に出力しているため、ファイルの行数は多いです。コメントと、main の前にあるディレクティブを除いた行数は、Ver.1 が 123 行、Ver.2 が 54 行でした。

実行結果

uchan@uchan-lifebook:~/workspace/github.com/uchan-nos/opela/compiler/bench$ time ./v1-nested-for_bench 

real	0m14.590s
user	0m14.567s
sys	0m0.000s
uchan@uchan-lifebook:~/workspace/github.com/uchan-nos/opela/compiler/bench$ time ./v1-nested-for_bench 

real	0m14.569s
user	0m14.560s
sys	0m0.001s
uchan@uchan-lifebook:~/workspace/github.com/uchan-nos/opela/compiler/bench$ time ./v1-nested-for_bench 

real	0m14.680s
user	0m14.643s
sys	0m0.009s
uchan@uchan-lifebook:~/workspace/github.com/uchan-nos/opela/compiler/bench$ time ./v2-nested-for_bench 

real	0m4.947s
user	0m4.935s
sys	0m0.004s
uchan@uchan-lifebook:~/workspace/github.com/uchan-nos/opela/compiler/bench$ time ./v2-nested-for_bench 

real	0m4.901s
user	0m4.892s
sys	0m0.005s
uchan@uchan-lifebook:~/workspace/github.com/uchan-nos/opela/compiler/bench$ time ./v2-nested-for_bench 

real	0m4.962s
user	0m4.957s
sys	0m0.001s

Ver.1 の速度測定

フィボナッチ数列の計算にかかる時間を,OpeLa,C,Python で比較してみました。 使用した OpeLa コンパイラのバージョンは 94d09ecd4221162689d67fd8986b00cde16b829b

計測対象のプログラム

計測に用いたソースコードは次の通りです。これは OpeLa のものですが,C,Python も同様のプログラムになっています。 使用した OpeLa バージョンでは標準出力を使えませんので,exit code で結果を出力します。C,Python も公平のために exit code で出力を行います。

$ cat fib.opl
func main() {
  fib(36) != 14930352;
}

func fib(n) {
  if n<=1 {
    n;
  } else {
    fib(n-1)+fib(n-2);
  }
}

計測環境

計測結果

結果を示します。平均を取ってない,適当な計測であることをご了承ください。

言語 実行時間
OpeLa 0.243 秒
C 0.117 秒
C -O3 0.084 秒
Python 3.643 秒

“C -O3” は C プログラムを最適化レベル 3 でコンパイルしたことを意味します。

OpeLa は最適化をしていない C(Clang)の 2 倍程度の時間がかかりましたが,愚直なスタックマシン実装ですから,まあ妥当なレベルでしょう。 Python の遅さが際立ちますね…

詳細結果

OpeLa

$ time sh -c "./fib_opela && echo ok"
ok

real	0m0.243s
user	0m0.243s
sys	0m0.000s

C

$ time sh -c "./fib_c && echo ok"
ok

real	0m0.117s
user	0m0.117s
sys	0m0.000s

Python

$ time sh -c "python3 fib.py && echo ok"
ok

real	0m3.643s
user	0m3.635s
sys	0m0.008s

コンパイルを含んだ時間計測

上記の結果は Python だけ構文解析などの時間が含まれてしまっています。 不公平なので,OpeLa と C に関してもコンパイル時間を含んだ時間を計測してみました。

OpeLa のコンパイル時間(0.046 秒)はそんなに遅くない,むしろ C のコンパイル時間(0.061 秒)より短いほどです。 OpeLa のコンパイラの実装は素直な感じですが,それがむしろ良いのかもしれません。

言語 実行時間(コンパイル時間を含む)
OpeLa 0.289 秒
C 0.178 秒
C -O3 0.143 秒
Python 3.643 秒

OpeLa

$ time sh -c "cat fib.opl | ./opelac > fib.s; nasm -f elf64 fib.s; cc -o fib_opela fib.o; ./fib_opela && echo ok"
ok

real	0m0.289s
user	0m0.285s
sys	0m0.007s

C

$ time sh -c "clang -o fib_c fib.c; ./fib_c && echo ok"
ok

real	0m0.178s
user	0m0.127s
sys	0m0.034s

C -O3

$ time sh -c "clang -O3 -o fib_c fib.c; ./fib_c && echo ok"
ok

real	0m0.143s
user	0m0.096s
sys	0m0.029s