A5:SQL Mk-2

開発のこと、日々のこと

Windows Subsystem for Linux で Java 9のAOT(事前)コンパイルを試してみた話

| 0件のコメント

2017/11/18 にJJUG CCC 2017 Fallという、Javaのカンファレンスに参加してきたのですが、Java 9でAOTコンパイルが導入されたよという話を聞いてきました。

M10 Javaで使えるもう一つのコンパイル方式 -AOT (#ccc_m10)

JavaはもともとJITコンパイルと呼ばれる実行時コンパイラが導入されているのですが、AOTコンパイルでは、プログラム実行前にJavaバイトコードをネイティブコードに変換してしまいます。

AOTコンパイルがJava 9で導入されるよとは聞いていたのですが、その後の情報が少なく、リリース時にも全然聞かなかったので、てっきりキャンセルされたのかと思っていました。

どうも、Java 9ではLinux版のみの対応でサポートも行われないようです。WindowsはJava10以降の導入らしい…。ガッカリ。

だけど、Windows 10にはWindows Subsystem for Linux (WSL)があるじゃあないか!!ということで試してみました。

 

1.Windows Subsystem for Linuxの有効化
最近のWindows 10はコントロールパネルの呼び出しが面倒くさいのですが、Windows+Rキーで「ファイル名を指定して実行」か、コルタナの入力域で「control」とだけ打てば、コントロールパネルが呼び出せます。
「プログラムと機能」から、「Windows の機能の有効化または無効化」を呼び出し、「Windows Subsystem for Linux」のチェックをONにします。

 

2.Ubuntu(とか)の導入
Microsoft StoreからUbuntuを検索し導入します。

Ubuntu以外もOpenSUSEやFedoraなんかもあるようですね。今回はUbuntuを入れてみました。

 

3.Java(もちろんLinux版)を導入

ここからはスタートメニューからUbuntuを起動して実行します。
以下のブログを参考にさせていただきました。
https://hirooka.pro/?p=9259

すみません、前半の内容よくわかりません。Java導入するのにPython必要なんですか?。インストール時の応答を自動化して要るっぽいのでしょうか。とりあえず、全部そのままコピペして実行しました。
導入できたら、「Java -version」できちんと導入されたことを確認します。

 

4.なんか実行してみる
とりあえず、手持ちのソートアルゴリズムを…。
Mas4Sort 自分がJJUG CCC 2017 FallでもセッションしたMasSort(3-way Mergesort)の兄弟で4-way…つまり、4分割版のマージソートです。これは、JITコンパイルのオーバーヘッドが大きいので今回のテストにはうってつけです。

(そもそもコードが(ムダに)長くなりがちなため、JavaよりC++のほうがMas4Sortアルゴリズムと相性がいい気がする)

以下のコマンドで10000000件の乱数の整数キーを持つオブジェクトのソートを10回繰り返してみます。

 

初回実行は約7.9秒、2回目以降はJITコンパイルが効いて速くなって約5.8秒…、ちなみにWindows版のJava9では、初回8.5秒、2回目以降は5.6~5.7秒くらいでした。Java VMのコンパイラの違いとかいろいろあるでしょうが、単純計算だけなら、Windows Subsystem for Linuxを使っているからと言ってそこまでオーバーヘッドが大きいわけではないようです。

 

5.AOTコンパイルを試してみる
JavaのAOTコンパイルのコマンドはjaotcです。なんだかよくわからないのだけど、クラスパスが指定できない?みたいな感じで、クラスパスのルートディレクトリに移動してからコンパイルしました。「–directory」とか「–serch-path」とかオプションがあるみたいなのだけど…。

オプションを見ると、jarファイルなんかも指定できるっぽいですね。…試してません。

 

6.AOTライブラリを指定して実行してみる
なんだかよくわからないのですが、「-XX:AOTLibrary」でライブラリファイル(.so)を指定するときは、先頭に「./」を付けてやらないとうまく動きませんでした。
ちなみにライブラリを複数指定するときは、「:」で繋ぐらしいです。

 

実行結果は…8.9~9.0秒くらい…遅くなってる!?なんで?。Windows Subsystem for Linuxなんて使っているせいなのか?、JavaのAOTコンパイル機能がまだ未成熟なのか…。
そもそも、JITコンパイルって、実行時に得られる状態をもとにコンパイルできるから、事前にコンパイルするより高速に実行できるんですよという触れ込みだったはずなので、実行時情報の取得できないAOTコンパイルはちょっと遅くなっちゃうのかも?とも思います。
まあ、Windows Subsystem for LinuxでJava動かしている時点で、パフォーマンス云々は検証しても意味ないのかもしれませんが…。

ただ、最初からコンパイルされているため、初回実行と2回目以降で実行時間に有意な差はないように見えます。遅くなったといってもインタプリタより早いでしょうから、1回しか実行されないバッチ処理などで真価を発揮するかもしれません。

 

2018/1/2 追記

その後調べたところ、AOTコンパイル時に –compile-for-tiered オプションを付加することで、初回実行時間はJITよりやや速く、2回目以降はJITと同等になることを確認しました。

 

以下も読んでみてください。

JJUG ナイトセミナー: 年送りビール&LT大会 2017/12/27

Javaで使えるもう一つのコンパイル方式 – AOT  … を無理やりWindowsでやってみた話

コメントを残す

必須欄は * がついています