RTTI

実行する時とかに -dinstr オプションをつけるとバイトコードが出るそうです。

let _ =
  print_int 12345;
  ()

みたいなコードは、

i@u ~/test/ocaml> gcaml -dinstr pr_test.ml
        const 12345
        push
        getglobal Pervasives!
        getfield 30
        apply 1
        const 0a
        return 1

とかになりました。 12345 を積んで、 Pervasives (Object とか Kernel とか Prelude とか Lobby とか言語ごとに違う最初のモジュールみたいなヤツぽい。 JS だったら実装ごとに違ったりとか) から関数探してきて apply 1 (1は引数の数だと思う) してる。そのまんまですな。 Gprint.eprint に書き換えると…

i@u ~/test/ocaml> gcaml -dinstr pr_test.ml
        const 12345
        push
        const 0
        push
        getglobal Builtintypes!
        getfield 1
        push
        const [0: [0: "int" 1]]
        makeblock 2, 0
        makeblock 2, 2
        makeblock 1, 0
        makeblock 1, 0
        push
        getglobal Gprint!
        getfield 3
        apply 2
        const 0a
        return 1

なんかややこいことになってますなぁ。型情報を第一引数として渡してるんでしょうけど、謎の makeblock とかでなんかよくわからないことしてますのう。ちなみに Printf.printf "%d\n" 12345 はこんな感じ。

i@u ~/test/ocaml> gcaml -dinstr pr_test.ml
        const 12345
        push
        const "%d\n"
        push
        getglobal Printf!
        getfield 1
        apply 2
        const 0a
        return 1

まぁ実行時型情報にはコストがかかるという話ですね。 printf は文字列のパースが入るからこのコードだけ見て速度推測してもしょうがないけど。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h