GraalVMをご存知ですか?
Oracleの作成した、多言語ランタイムです。Javaを各OS向けにネイティブコンパイルすることができます。
フットプリントの軽さや、起動の速さなどを目指しており、Dockerなど、コンテナ技術との組み合わせが期待される技術です。
というわけで、速さを確認してみます。
2019/03/17 修正:
dotnetコマンドでDebugビルドで計測していたので、Releaseビルドで計測し直しました。
2019/03/19 修正:
GraalじゃなくてGraalVMのほうが正しくね?とコメントいただきました。そのとおりだと思ったので修正しました。
フィボナッチで対戦
随分前に、Node.jsをつかう → はやい という記事を書きました。
そのプログラムを使用して、Node.js、Java、GraalVMを対決させてみます。
(Graal以外のランタイムがちょっと古いのは許してほしいです。)
環境
MacBook Pro (Retina, 13-inch, Late 2012)
プロセッサ 2.9 GHz Intel Core i7
メモリ 8 GB 1600 MHz DDR3
Node.js
function fib(n){
if(n <= 1) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
console.log(fib(40));
結果。
$ node -v
v10.11.0
$ time node fib.js
102334155
real 0m1.752s
user 0m1.494s
sys 0m0.078s
ふむ。
Java
続きまして、Java。
public class fib {
static int fib(int n) {
if(n <= 1) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
public static void main(String[] arg){
System.out.println(fib(40));
}
}
実行
$ java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
$ javac fib.java
$ time java fib
102334155
real 0m0.555s
user 0m0.536s
sys 0m0.028s
うぉぉ、、、早い。Node.jsより早いのは意外。
GraalVM
コードはJavaと一緒。
$ native-image --version
GraalVM Version 1.0.0-rc13
$ native-image fib
//省略、、、すっごい時間かかる。
$ time ./fib
102334155
real 0m0.737s
user 0m0.728s
sys 0m0.005s
あれ。。。Javaのほうが早い。。。。
というわけで、GraalVMにとっては残念な結果。
というか、Javaがすごく早くてびっくりしました!
番外編 Golang
早い、軽いの代名詞、Golangで同様の実験をしてみました。
package main
import "fmt"
func fib(n int) int {
if(n <= 1) {
return n
}
return fib(n - 1) + fib(n - 2)
}
func main() {
fmt.Println(fib(40))
}
$ go version
go version go1.11 darwin/amd64
$ go build fib.go
$ time ./fib
102334155
real 0m0.767s
user 0m0.759s
sys 0m0.006s
GraalVMと同じくらい。
番外編その2 C#(Dotnet)
Javaと同様のVM言語。
class fib {
public static long Fib(int n) {
if (n <= 1)
return n;
return Fib(n - 1) + Fib(n - 2);
}
static void Main(string[] args) {
System.Console.WriteLine(Fib(40));
}
}
$ dotnet --version
2.1.101
//プロジェクトをdotnet new consoleとかで作ってから、、、
$ dotnet build -c Release
//いろいろ出る。
$ time dotnet bin/Debug/netcoreapp2.0/demo.dll
102334155
real 0m3.962s
user 0m3.922s
sys 0m0.031s
とてつもなく遅い。。。コンテナ時代には向かない言語かな。。。
2018/03/17 追記
すいません。Debugビルドの方で実行していました。
Releaseビルドで実行した結果です。
$ time dotnet bin/Release/netcoreapp2.0/demo.dll
102334155
real 0m1.021s
user 0m0.932s
sys 0m0.054s
GraalVM、Goには及ばない感じだが、そこそこの速度が出ています。
番外編その3 python
def fib(n):
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
print(fib(40))
$ python3 --version
Python 3.7.0
$ time python3 fib.py
102334155
real 0m56.411s
user 0m55.466s
sys 0m0.347s
お察し。
結果
Javaがめっちゃ早い。
こういう、小さいアプリケーションはJavaの苦手領域だと思っていたので、非常に驚きました。
Javaでいいじゃない。