たのしい
Graal/Truffle
自己紹介
- 山名 洋平
- Opt Technologies
- Java, PHP, Scala
- twitter
@vertical_blank
話すこと
-
graal とは
-
truffle とは
-
遊んでみる
-
もろもろ
Graal
Javaで記述されたJITコンパイラ
- java8ベースのバイナリが配布されている
- truffleと以下の実行エンジンを同梱
- JavaScript( + node.js)
- Ruby
- R
- ahead-of-time compile
classから実行ファイルを生成
Truffle
インタプリタ実装フレームワーク
- 抽象構文木を表すクラス
- 各言語の実行エンジンは、対象言語のコードを
上記(を継承したクラス)へ変換 - 抽象構文木はJITの対象となる
遊んでみる
- 入手
- 内容物
- NodeJS on GraalVM
- AltJava
入手
- Oracle Labs
- 「otn graal」で検索
- 対象OS
- linux
bash on windows でもjsは動いた - Mac
- Solaris
- linux
- バージョン
- 5/20時点では0.22
- 6/16時点では0.24
内容物
$ ls bin
R aot-image graalvm java javadoc node ruby
Rscript g irb javac js npm
なんか色々入ってる!
REPL
$ bin/graalvm --shell
GraalVM MultiLanguage Shell 0.24
Copyright (c) 2013-7, Oracle and/or its affiliates
JS version 0.9
R version 0.1
Ruby version 2.3.3
Usage:
Use Ctrl+L to switch language and Ctrl+D to exit.
Enter -usage to get a list of available commands.
JS> console.log('hello js')
hello js
R> print('hello R')
[1] "hello R"
Ruby> puts 'hello Ruby'
hello Ruby
nil
NodeJS on GraalVM
node
$ bin/node
> var fs = require('fs')
undefined
> fs.read
fs.read fs.readFile fs.readFileSync fs.readSync fs.readdir fs.readdirSync fs.readlink fs.readlinkSync
> java.util.Arrays.asList(1, 2, 3, 4)
'[1, 2, 3, 4]'
node.jsのモジュールが一式使える!
Javaクラスにもアクセスできる!
ライブラリ
const lodash = require('lodash')
const FastList = org.eclipse.collections.impl.list.mutable.FastList;
const UnifiedMap = org.eclipse.collections.impl.map.mutable.UnifiedMap;
const pair = org.eclipse.collections.impl.tuple.Tuples.pair;
const toJsArray = (vs) => vs.injectInto([], (vs, v) => vs.concat(v));
const javaList = FastList.newListWith(1, 2, 3, 4);
const jsList = toJsArray(javaList);
console.log(jsList)
const javaMap = UnifiedMap.newMapWith(pair('a', 1), pair('b', 2));
const jsMap = lodash.zipObject(
toJsArray(javaMap.keysView()),
toJsArray(javaMap.valuesView()));
console.log(jsMap)
ライブラリ
- npm modules
一手間掛かるが、ネイティブ拡張も- sqlite3
- node-sass
- -cp でjavaライブラリも使える
- さりげなくjsのArrowFunctionがjava8のlambdaとして書けている
NodeJSからFuture
function Task(f) {
return new java.util.concurrent.Callable(f);
}
const atom = new AtomicInteger();
let count = 0;
const tasks = [1, 2, 3, 3, 3, 3, 3, 3, 4, 5].map(i =>
Task(() => {
atom.getAndIncrement();
count++;
sleep(i * 1000);
return Thread.currentThread().getId();
})
);
真の並列処理がJSに!
JS <=> Ruby
function loop(n) {
var add = Interop.import("add");
var i = 0;
var sum = 0;
while (i <= n) {
sum = add(sum, i);
i = add(i, 1);
}
return sum;
}
Interop.eval("application/x-ruby",
"def add(a, b) a + b; end;");
Interop.eval("application/x-ruby",
"Truffle::Interop.export_method(:add);");
console.log(loop(process.argv[2]));
速度比較
function fibonacci(n) {
if (n < 2)
return 1;
else
return fibonacci(n-2) + fibonacci(n-1);
}
var res;
for (var i = 30; i < 46; i++){
var start = new Date();
res = fibonacci(i);
var end = new Date();
log("Input: " + i + " Result: " + res + ", Time: " + (end - start));
}
低いほど優秀
AltJava
$ JAVA_HOME=. scala
scala> :paste
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
val engine = PolyglotEngine.newBuilder().build();
engine.eval(Source.newBuilder("print('Hello polyglot world JavaScript!');")
.mimeType("application/javascript").name("").build()).get();
engine.eval(Source.newBuilder("puts 'Hello polyglot world Ruby!'")
.mimeType("application/x-ruby").name("").build()).get();
engine.eval(Source.newBuilder("print('Hello polyglot world R!');")
.mimeType("application/x-r").name("").build()).get();
Hello polyglot world JavaScript!
Hello polyglot world Ruby!
[1] "Hello polyglot world R!"
-
GraalVM上でもちゃんとAltJavaは動く
-
groovyshとscala REPLで確認
-
Scala 2.12.1だとエラーでコケる
2.12.2 にUpdate!
- 動いたもの
- websocket
- reactのシンプルなSSR
https://github.com/mhart/react-server-example
-
動かなかったもの
- vue-cli
他に試したもの
もろもろ
-
GraalとJava9
- その他言語
- 参考にしたもの
GraalとJava9
- HotSpotVMの一部にhttps://github.com/dmlloyd/openjdk
- truffleはmavenに
https://mvnrepository.com/artifact/com.oracle.truffle
-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
手元では未確認
GraalとJava9
- まだjmod形式ではない
- 各言語の実行エンジンは同梱されていない
- TruffleNode, TruffleJSについてはソースも公開されていない
-
そもそもJava9が揉めてる 😇
その他言語
- python
https://github.com/securesystemslab/zippy - LLVM
https://github.com/graalvm/sulong
- groovyあたりがtruffleベースになる日が来るかも
- なんだかんだ起動と最適化に時間は掛かる
groovyservみたいな仕組みがあれば…?
参考にしたもの
宣伝
Graal
By yohei yamana
Graal
- 2,893