雨谷の日和

過去20年で2,700を超えるアニメの第1話だけは見続けた僕のお勧めアニメがハズレなはずがない

JavaのAOTコンパイラ

さて、ちょっとここで比較項目を増やそうと思う。
いままでJavaについてはHotSpotでの最適化のみを取り上げて比較してきた。
しかしJavaでは実行時最適化のHotSpotの他にも、Cと同じような実行前最適化の技術の研究も為されている。
Ahead of time(AOT)コンパイラと呼ばれるその技術は、Javaソースコードもしくはバイトコードから、ネイティブな実行バイナリを作成しようという考え方を実現するものである。
今回は、gcc3.3.1(cygwin版)に付属のgcjというAOTコンパイラを実際に使ってみて、その実行性能を比較してみたいと思う。
理論上は、Cと同じくネイティブなレベルで最適化を掛けることができるはずなので、その実行性能の傾向はHotSpotでのJavaのそれよりも、Cのそれに近いことが期待される。
もちろん、gcjは未だ実装の進行中の未成熟なものなので、理論どおりには行かないだろうということは念頭においておくべきだろう。
参考サイト→「GNU gcjガイド


まず、gcjを使ってJavaソースコードから実行バイナリを作ってみよう。
以下のようにする。

gcj -o jtest.exe --main=Test Test.java

上記を実行すると、全く最適化をしないで実行バイナリを作成する。
「--main」オプションで、最初に実行するmainメソッドを含むクラスを指定するところがポイントとなる。
もちろん、クラスパスなどの細かな設定が必要なときには、別途様々なオプションを指定する必要があるが、今回は単一のクラスをただコンパイルするだけなので複雑な指定は必要ない。


あと、gcjではgccでのコンパイルと同じように-Oでの最適化レベルの指定が出来る。

gcj -o jtest.exe -O3 --main=Test Test.java

更に、gcjに固有な最適化オプションとしては以下のようなものもある。

  • 「-fno-bounds-check」:配列の境界チェックを行わない
  • 「-fno-store-check」:配列代入時の型チェックを行わない

こういったものを指定すると、以下のような感じになる。

gcj -o jtest.exe -O3 -fno-bounds-check -fno-store-check --main=Test Test.java

得られた実行バイナリは、通常のexeファイルと同様に実行することが出来る。


次回は、上記のようにして得られたものを実際に実行して見ることにしよう。