Java
Python
JavaScript
Go
graalvm

GraalVMを使う → おそい (というか、Javaが十分早い。Goよりも。)

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でいいじゃない。