GraalVMはどれだけ遅いか

GraalVM流行ってますね。
そして、多くの人はGraalをAOTとして使うnative-imageのことだけをGraalVMと言ってたりします。
ご安心を。このエントリではGraalをJITとして使うHotSpotモードとGraalをAOTとして使うnative-imageの両方が遅いという話です。

GraalVMは速い、と言われてますが、残念ながらHotSpotモードでC2より速い結果を手元では出せていません。
公式ブログでは1.7倍から5倍速くなると書いてますけど、手元では再現できてません。
Under the hood of GraalVM JIT optimizations - graalvm - Medium

native-imageは速い、というのはよくありますが、これはネイティブ化によりJVMの起動時間や最適化の時間、最適化されずに動く時間が省略されるので起動が速い、という話です。長く動くプロセスの場合、そういった起動にかかる時間というのは無視できるようになり、実行時に集めた情報を使って最適化するJITのほうが速いです。

用語について

ところでここで用語の確認を。
GraalVMというのは、Javaで書かれたJITコンパイラGraalを中心とした多言語環境です。
普通にGraalをJavaJITコンパイラとして使うのがGraalVMのHotSpotモードです。ようするにjavaコマンドです。
Graalの最適化機構を一般のスクリプト言語から使えるようにしてJavaScriptRubyJITコンパイラにしてしまうのがTruffleです。
そして、Graalを事前にJavaコードに適用してネイティブ化するというのがnative-imageです。

計測

ということで、どのくらい遅いか比べてみます。
コードはこのレイトレ。
https://github.com/kishida/smallpt4j/blob/original/src/main/java/naoki/smallpt/SmallPT.java
commonsのFastMathを使っているので、通常のjava.lang.Mathに置き換えて実行します。また、ループ中のSystem.out.printlnはコメントアウトしました。
それはそうと、以前はこのコードはImageIOを使っているのでGraalVMでネイティブ化できなかったのですが、いまではできるようになってます。
実行するとこんな感じのPNG画像が出力されます。
f:id:nowokay:20190627042056p:plain

GraalVM 19.0.2 CE

ここではWindowsで動かしてみました。GraalVMは19.0.2CEです。
まずはHotSpotモード。

C:\Users\naoki\Documents\prj>java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-20190603180034.buildslave.jdk8u-src-tar--b03)
OpenJDK 64-Bit GraalVM CE 19.0.2 (build 25.212-b03-jvmci-19-b04, mixed mode)

C:\Users\naoki\Documents\prj>java SmallPT
Samples:40 Type:master Time:PT9.713S

10秒弱。

ネイティブ化してみます。

C:\Users\naoki\Documents\prj>native-image SmallPT
[smallpt:21796]    classlist:   1,793.30 ms
...
[smallpt:21796]        write:     786.36 ms
[smallpt:21796]      [total]:  26,307.39 ms

C:\Users\naoki\Documents\prj>smallpt
Samples:40 Type:master Time:PT45.234S

45秒。だいぶ遅い!

GraalVM 19.0.2 EE

ついでにEEでも試してみます。

C:\Users\naoki\Documents\prj>java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b31)
Java HotSpot(TM) 64-Bit GraalVM EE 19.0.2 (build 25.212-b31-jvmci-19-b04, mixed mode)

C:\Users\naoki\Documents\prj>java SmallPT
Samples:40 Type:master Time:PT10.281S

10秒強。あんま変わらん。

ではネイティブ化。

C:\Users\naoki\Documents\prj>native-image SmallPT
[smallpt:43056]    classlist:   2,165.31 ms
...
[smallpt:43056]        image:     788.17 ms
Warning: Generating and stripping of debug info not supported on Windows[smallpt:43056]        write:     775.12 ms
[smallpt:43056]      [total]:  29,450.40 ms

C:\Users\naoki\Documents\prj>smallpt
Samples:40 Type:master Time:PT13.039S

13秒!CEに比べるとめっちゃ速い!

OpenJDK

それではC2版。つまりふつうのOpenJDK

$ java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b03)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b03, mixed mode)

$ java SmallPT
Samples:40 Type:master Time:PT6.795S

6.8秒。GraalVMに比べるとだいぶ速いです。

OpenJDKの11でも試してみます。

$ java -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

$ java SmallPT
Samples:40 Type:master Time:PT5.8484946S

5.8秒。お、ちょっと速くなってる!

まとめ

ということで、まとめるとこう。
ついでにMacでも計測しています。Windowsが8コアでMacが4コアなので、ちょうど倍くらいの時間がかかってますね。CEのnative-imageがそれほど遅くないのだけど、コア数によるものかWindowsMacの違いか気になるところ。

GraalVM CE HotSpot GraalVM CE Native GraalVM EE HotSpot GraalVM EE Native OpenJDK 8 OpenJDK 11
Windows(i7-8Cores) 9.713 45.234 10.281 13.039 6.795 5.848
Mac(i7-4Cores) 20.966 47.069 18.797 19.135 16.783 12.594

グラフにするとこう。
f:id:nowokay:20190627045257p:plain

ということで、GraalVMのネイティブイメージは起動以外は速くない むしろ遅い、GraalVM EEのネイティブイメージはCEに比べるとかなり速いけどHotSpotモードほどではない、JDKは8から11でも速くなってる、という結果になりました。
LinuxでやればGraalは速いという噂もあります。

7/4追記 19.1.0が出てたので試してみたけど、CEのnative-imageがちょっと速くなった?

CE HotSpot CE Native EE HotSpot EE Native
19.1.0 Win 10.676 43.419 10.787 12.972
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy