SlideShare a Scribd company logo
1 of 51
Download to read offline
ラムダと invokedynamic の蜜月
宮川 拓 / @miyakawa_taku
2013-07-22 JJUG ナイトセミナー
自己紹介
• 宮川 拓 (@miyakawa_taku) と申します
• SI 屋です
• JJUG 幹事です
• Kink という JVM 言語を開発しています
– https://bitbucket.org/kink/kink
1
要旨
• ラムダ式の実行は invokedynamic で実現さ
れます。その理由と、実行の流れを見ます
– 論点整理
– ラムダ式の実行 (1)
– invokedynamic の復習
– ラムダ式の実行 (2)
– なぜ invokedynamic?
– ラムダの直列化
2
※注記
この資料は、 JDK, JRE の「仕様」と「実装」を厳密に区別していません。
論点整理
3
静的構造
4
関数型インタフェース
ラムダのクラス
ラムダのインスタンス
instance-of
implements
Comparable
Comparable<String> c = (x, y) -> x.length() - y.length();
c
c のクラス
実行の流れ
5
Comparable<String> c = (x, y) -> x.length() - y.length();
Collections.sort(strings, c);
main Collections
ラムダ
sort compare / 処理の中身の実行
new / ラムダ式の実行
今回の主な論点
ラムダ式の実行 (1)
6
ラムダのクラスの実行時生成
• 匿名クラスがコンパイル時に生成されるのに
対し、ラムダのクラスは実行時に生成されます。
まずはそれを確かめます
7
関数型インタフェース
ラムダのクラス
ラムダのインスタンス
instance-of
implements
実行時に生成
匿名クラスをコンパイル
• 匿名クラスは、「外側のクラス名$連番」という
名前で、コンパイラによって生成されます
8
$ cat >AnonClass.java
import java.util.*;
class AnonClass {
Comparator<String> comparator() {
return new Comparator<String> {
@Override public int compare(String x, String y) {
return x.length() – y.length();
}
};
}
}
$ javac AnonClass.java && ls *.class
AnonClass$1.class
AnonClass.class
ラムダをコンパイル
• 同等のラムダをコンパイルしても、対応するク
ラスファイルは生成されません
9
$ cat >Lambda.java
import java.util.*;
class Lambda {
Comparator<String> comparator() {
return (x, y) -> x.length() - y.length();
}
}
$ javac Lambda.java && ls *.class
Lambda.class
ラムダのクラスの生成タイミング
• ラムダのクラスが、コンパイル時には生成され
ないことが分かりました
• したがって、実行時のどこかのタイミングで生
成されているはずです
10
ラムダを含む
ソース
クラス
ファイル
ラムダの
クラスの生成
ラムダの
インスタンス化
コンパイル (JDK) 実行 (JVM)
この時点では
ラムダのクラスは
生成されない
どこかの
タイミング
ラムダのクラスの名前
• まずはラムダのクラスの名前を確認します
11
$ cat >Lambda.java
import java.util.*;
public class Lambda {
public static void main(String[] args) {
Comparator<String> c = (x, y) -> x.length() - y.length();
System.out.println(c.getClass());
}
}
$ javac Lambda.java && java Lambda
class Lambda$$Lambda$1
生成のタイミング
• loadClass(name) すると、ラムダ式を実行する
タイミングでラムダのクラスが出現しているこ
とが分かります
12
$ cat >Lambda.java
...
System.out.println(loadClassOrNull("Lambda$$Lambda$1"));
Comparator<String> c = (x, y) -> x.length() - y.length();
System.out.println(loadClassOrNull("Lambda$$Lambda$1"));
...
$ javac Lambda.java && java Lambda
null
class Lambda$$Lambda$1
ラムダ式実行の過程
• ラムダ式を実行するタイミングで、ラムダのク
ラスが生成されていることが分かりました
• ではラムダ式は、バイトコードのレベルでは、ど
のような過程で実行されているのでしょうか?
13
ラムダ式のバイトコード
• ラムダ式を含むプログラムのクラスファイルを、
javap コマンドで逆アセンブルします
14
$ cat >Lambda.java
import java.util.function.*;
class Lambda {
IntUnaryOperator adder(int delta) {
return n -> n + delta;
}
}
$ javap -c -p Lambda.class
... (次ページ) ...
javap による逆アセンブルの結果
15
class Lambda {
...
java.util.function.IntUnaryOperator adder(int);
Code:
0: iload_1
1: invokedynamic #2, 0
6: areturn
private static int lambda$0(int, int);
Code:
0: iload_1
1: iload_0
2: iadd
3: ireturn
}
再度 Java プログラム風に解釈
• ラムダの処理の中身は lambda$0 というメ
ソッドに記述されます
• ラムダ式の実行は invokedynamic 命令の呼
び出しになっています
16
class Lambda {
IntUnaryOperator adder(int delta) {
return <invokedynamic>(delta);
}
private static int lambda$0(int delta, int n) {
return n + delta;
}
}
ここまでの整理
• 分かったこと
– ラムダのクラスはラムダ式実行の際に生成されま
す
– ラムダ式の実行は invokedynamic 命令です
• 推定できること
– invokedynamic 命令をきっかけとして、ラムダの
クラスが生成され、またラムダのインスタンスが生
成されるはずです
17
invokedynamic の復習
18
invokedynamic の復習
• ラムダ式実行の流れを追いかけるにあたり、
まずは invokedynamic をおさらいします
19
invokedynamic とは
• 本来は、 JRuby など、 Java 以外の言語処理
系のために、 Java SE 7 で追加されたメソッド
呼び出し命令です
• invokevirtual, invokeinterface など、 Java SE
6 までのメソッド呼び出し命令と異なり、呼び
出す処理が実行時に選択できます
20
Java のメソッド呼び出し手順
• どの呼び出し命令でも、手順は大体同じです
21
int result = receiver.doSomething(arg0, arg1);
receiver
arg0
receiver
arg1
arg0
receiver 戻り値
invokexxx
レシーバと引数をスタックに積む 呼び出し
結果も
スタックに
void
以外の場合
Java SE 6 までの呼び出し命令
• Java SE 6 までの呼び出し命令は、いずれも
Java 言語と密に結びついてます
– メソッドは再定義されない
– 名前、引数の型、レシーバのクラスが決まれば、呼
び出すべき処理が定まる
22
invokestatic static メソッドを呼び出す
invokespecial コンストラクタ、 private メソッド等を呼び出す
invokevirtual クラスに属するメソッドを呼び出す
invokeinterface インタフェースに属するメソッドを呼び出す
Java 以外の言語処理系の実装
―Java SE 6 以前
• Java 言語にない機構(メソッド再定義など)を
実現するため、処理系が呼び出しに介入
→JVM による実行時最適化が効きづらい
23
array.join
invoke
virtual
処理系
size Func@42
join Func@123
検索
def join
...
invoke
virtual
関数テーブル
Java 以外の言語処理系の実装
―Java SE 7 以降
• invokedynamic を使って、処理系を介さずに、
直接メソッドが呼び出せるようになりました
→JVM による実行時最適化が効きやすい!
24
array.join
invokedynamic def join
...
invokedynamic の道具立て
• 呼び出し元 (CallSite) ごとに、ブートストラップ
メソッドで、呼び出し先の関数ポインタ
(MethodHandle) を登録
25
Method
Handle
オブジェクト
CallSite
オブジェクト
ブートストラップ
メソッド <<create>>
初回呼び出しの前に
実行
対象の
処理
呼び出し元
<<create>>
呼び出し
ブートストラップメソッド
• static である必要がある
• ブートストラップメソッドの引数
– Lookup: MethodHandle のファクトリ
– String: 「メソッド名」だが、使わなくても可
– MethodType: invokedynamic の引数型と戻り値型
– 任意個数の定数
• ブートストラップメソッドの戻り値
– MethodHandle の初期値が紐付けられた CallSite
26
ブートストラップメソッドの例
• メソッドを呼び出した後、強制的に戻り値を
42 にする MethodHandle を生成
27
static CallSite bsm(Lookup lu, String name, MethodType mt)
throws Exception {
MethodHandle vmh = lu.findVirtual(mt.parameterType(0), name, vmt);
return new ConstantCallSite(filterReturnValue(vmh,
dropArguments(constant(int.class, 42), 0, int.class)));
}
• 以上のように、個々の invokedynamic の動作は、
ブートストラップメソッドを見れば見当が付きます
ラムダ式の実行 (2)
28
ラムダ式の invokedynamic
• 先ほど見たところでは、ラムダ式の実行は、
invokedynamic 命令の実行として実装され
ていました
→紐付けられているブートストラップメソッドを見
れば、実際の動作がわかるはずです
29
ラムダ式の実行の流れ
• ラムダ式の実行の invokedynamic には、
java.lang.invoke.LambdaMetaFactory の
metaFactory メソッドがブートストラップメソッ
ドとして紐付いています
30
invoke
dynamic
<<ブートストラップ>>
LambdaMetaFactory
#metaFactory
ラムダの
インスタンス化
2 回目以降の
実行
1. ラムダのクラスを生成
2. ラムダをインスタンス化する
MethodHandle を生成
LambdaMetaFactory
#metaFactory
31
CallSite metafactory(Lookup lookup, // MethodHandle のファクトリ
String name, // 関数型インタフェースの唯一の抽象メソッド (SAM) の名前 (例: compare)
MethodType invokedType, // 命令の引数・戻り値型
MethodType samMethod, // SAM の引数・戻り値型
MethodHandle implMethod, // 処理本体のメソッド (例: lambda$0)
MethodType instantiatedSamType) // 型パラメータ適用後の SAM の引数・戻り値型
シグネチャ
1. これらの情報を元にラムダのクラスを生成
• 引数をフィールドに格納するコンストラクタ
• 処理本体のメソッドを呼び出す SAM の実装
2. ラムダをインスタンス化する MethodHandle を生成、
CallSite に紐付け
最終的に実行される処理
32
class Lambda {
static class Lambda$1 implements IntUnaryOperator {
private final int delta;
Lambda$1(int delta) { this.delta = delta; }
@Override public int applyAsInt(int n) {
return lambda$0(this.delta, n);
}
}
IntUnaryOperator adder(int delta) {
return <invokedynamic: new Lambda$1(delta)>;
}
private static int lambda$0(int delta, int n) {
return n + delta;
}
}
metaFactory
が生成
→ 結局、やってることは匿名クラスと(ほぼ)同じ!
なぜ invokedynamic?
33
なぜ invokedynamic?
• invokedynamic によるラムダ式の実行は、動
作としては匿名クラスと似たようなものでした
• なぜ、わざわざ invokedynamic を使うので
しょうか?
→(1) クラスファイルが少なくなるおかげで、起動が
速くなる、かもしれません
→(2) JVM が LambdaMetaFactory を独自に実装
することで、最適なインスタンス生成の方法を選
択できるようになります
34
(1) 起動時間
• Java SE 8 では、 Streams API の採用によって、
プログラム中で全面的にラムダ式が利用され
ることが想定されています(実態はどうあれ!)
• その際、ラムダ式を匿名クラス方式で実装す
ると、クラスファイルの数が飛躍的に増えるた
め、クラスローディングが遅くなってしまいます
• invokedynamic で、クラスを実行時に生成す
れば、起動時間が抑えられる、かもしれません
35
匿名クラスとラムダ式の起動時間比較
• 5,000 個の匿名クラス/ラムダをインスタンス
化するプログラムを実行(各10回)
36
平均
2,041ms
2,375ms
CPU: Core i3-2120T (2.6 GHz)
OS: Arch Linux, カーネル: 3.9.9-1-ARCH
JVM: JDK-8 build b99 (64-bit)
匿名クラス<ラムダ式 の考察
• 匿名クラスの実行時間増加要因
A) I/O
B) jar の解凍
• ラムダ式の実行時間増加要因
C) ブートストラップメソッド呼び出し(それにともな
う MethodHandle 作成など)
D) バイトコード生成
37
A+B < C+D となった?
(2) インスタンス生成戦略の選択
• LambdaMetaFactory は JVM が提供する
API です。したがって、実行時に JVM に都合
のよい方法でインスタンスが生成できます
• 可能な選択肢:
– 1 つのラムダ式ごとに 1 つのクラスを生成(既述)
– 外部の値を参照しないラムダ式であれば、シング
ルトンインスタンスを戻す(後述)
38
シングルトンインスタンス
• 次のラムダ式は、外側の変数に依存していな
いため、何度実行しても、同じ働きのインスタ
ンスを戻します
→この場合、シングルトンインスタンスを毎回使
い回せばいいはずです
39
Comparator<String> comparator() {
return (x, y) -> x.length() - y.length();
}
シングルトンインスタンス: 実行の流れ
• ラムダの処理の本体が、外側の変数に依存し
ていない場合、ラムダ式はシングルトンインス
タンスを戻します
40
invoke
dynamic
<<ブートストラップ>>
LambdaMetaFactory
#metaFactory
シングルトン
インスタンス
2 回目以降の
実行
1. ラムダのクラスを生成
2. ラムダのシングルトンインスタンスを生成
3. シングルトンインスタンスを戻す
MethodHandle を生成
シングルトンインスタンス: 確認
41
$ cat >Lambda.java
import java.util.*;
public class Lambda {
static Comparator<String> comparator() {
return (x, y) -> x.length() - y.length();
}
public static void main(String[] args) {
System.out.println(comparator());
System.out.println(comparator());
System.out.println(comparator());
}
}
$ javac Lambda.java && java Lambda
Lambda$$Lambda$1@84aee7
Lambda$$Lambda$1@84aee7
Lambda$$Lambda$1@84aee7
その他の可能なインスタンス生成戦略
• 1 つの関数型インタフェースごとに 1 つのクラ
スを生成。リフレクション経由で処理本体を呼
び出し
• MethodHandle を関数型インタフェースに直
接ラップする機構を用意して、それを使う
42
ラムダの直列化
43
ラムダの直列化
• 関数型インタフェースが Serializable を拡張
している場合、ラムダのインスタンスは直列化
できる必要があります
– 直列化(ラムダ→バイト列)、非直列化(バイト列→
ラムダ)した時、元のラムダと同じように機能する
必要がある
• ラムダのクラスが実行時に生成される時、どう
したら直列化・非直列化できるのでしょうか?
→ writeReplace / readResolve を使う
44
直列化の流れ
45
ラムダ
インスタンス
SerializedLambda バイト列
writeReplace
インタフェース名、処理本体
のメソッド名など、ラムダを構
成する静的情報を保持
defaultWriteObject
非直列化の流れ
46
defaultReadObject
ラムダ
インスタンス
SerializedLambdaバイト列
★
★: 静的情報を元にラムダを復元
SerializedLambda ラムダ式を含むクラス
ラムダ
readResolve
$deserializeLambda$
<<create>>
invokedynamic
コンパイル時に生成
総括
47
総括
• ラムダ式は匿名クラスの単純な構文糖ではあ
りません。 invokedynamic 命令を使って、クラ
スを実行時に生成しています
• これにより、 JVM がラムダのインスタンスの生
成方法を選べるので、実行時最適化の余地
が大きくなります
48
参考文献
49
参考文献
• Java SE 8 API Specification
– http://download.java.net/jdk8/docs/api/overview-summary.html
• JSR-335
– http://jcp.org/en/jsr/detail?id=335
• Brian Goetz “From Lambdas to Bytecode”
– http://wiki.jvmlangsummit.com/images/1/1e/2011_Goetz_Lambd
a.pdf
• 宮川 拓「Lambda 式に invokedynamic を使うのかもしれな
い話」
– http://d.hatena.ne.jp/miyakawa_taku/20120728/1343478485
50

More Related Content

What's hot

C#実装から見るDDD(ドメイン駆動設計)
C#実装から見るDDD(ドメイン駆動設計)C#実装から見るDDD(ドメイン駆動設計)
C#実装から見るDDD(ドメイン駆動設計)Takuya Kawabe
 
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードShigenori Sagawa
 
5分でわかるクリーンアーキテクチャ
5分でわかるクリーンアーキテクチャ5分でわかるクリーンアーキテクチャ
5分でわかるクリーンアーキテクチャKenji Tanaka
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること信之 岩永
 
ゼロ幅スペースという悪夢
ゼロ幅スペースという悪夢ゼロ幅スペースという悪夢
ゼロ幅スペースという悪夢swamp Sawa
 
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)NTT DATA Technology & Innovation
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメYoji Kanno
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはJun-ichi Sakamoto
 
node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成shigeki_ohtsu
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところY Watanabe
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みChihiro Ito
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ増田 亨
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門Tadahiro Ishisaka
 
Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2Norito Agetsuma
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐりKazuyuki TAKASE
 
Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Masahito Zembutsu
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホンYou_Kinjoh
 

What's hot (20)

Kotlinアンチパターン
KotlinアンチパターンKotlinアンチパターン
Kotlinアンチパターン
 
C#実装から見るDDD(ドメイン駆動設計)
C#実装から見るDDD(ドメイン駆動設計)C#実装から見るDDD(ドメイン駆動設計)
C#実装から見るDDD(ドメイン駆動設計)
 
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコード
 
5分でわかるクリーンアーキテクチャ
5分でわかるクリーンアーキテクチャ5分でわかるクリーンアーキテクチャ
5分でわかるクリーンアーキテクチャ
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
ゼロ幅スペースという悪夢
ゼロ幅スペースという悪夢ゼロ幅スペースという悪夢
ゼロ幅スペースという悪夢
 
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
 
node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成node-gypを使ったネイティブモジュールの作成
node-gypを使ったネイティブモジュールの作成
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
 
Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり
 
Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホン
 

Viewers also liked

JSR 352 “Batch Applications for the Java Platform”
JSR 352 “Batch Applications for the Java Platform”JSR 352 “Batch Applications for the Java Platform”
JSR 352 “Batch Applications for the Java Platform”Norito Agetsuma
 
Java 7 invokedynamic の概要
Java 7 invokedynamic の概要Java 7 invokedynamic の概要
Java 7 invokedynamic の概要Taku Miyakawa
 
Lambda: A Peek Under The Hood - Brian Goetz
Lambda: A Peek Under The Hood - Brian GoetzLambda: A Peek Under The Hood - Brian Goetz
Lambda: A Peek Under The Hood - Brian GoetzJAX London
 
Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点) Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点) Norito Agetsuma
 
JSFとJAX-RSで作る Thin Server Architecture #glassfishjp
JSFとJAX-RSで作る Thin Server Architecture #glassfishjpJSFとJAX-RSで作る Thin Server Architecture #glassfishjp
JSFとJAX-RSで作る Thin Server Architecture #glassfishjpToshiaki Maki
 

Viewers also liked (6)

JSR 352 “Batch Applications for the Java Platform”
JSR 352 “Batch Applications for the Java Platform”JSR 352 “Batch Applications for the Java Platform”
JSR 352 “Batch Applications for the Java Platform”
 
Java 7 invokedynamic の概要
Java 7 invokedynamic の概要Java 7 invokedynamic の概要
Java 7 invokedynamic の概要
 
Project Lambdaの基礎
Project Lambdaの基礎Project Lambdaの基礎
Project Lambdaの基礎
 
Lambda: A Peek Under The Hood - Brian Goetz
Lambda: A Peek Under The Hood - Brian GoetzLambda: A Peek Under The Hood - Brian Goetz
Lambda: A Peek Under The Hood - Brian Goetz
 
Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点) Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点)
 
JSFとJAX-RSで作る Thin Server Architecture #glassfishjp
JSFとJAX-RSで作る Thin Server Architecture #glassfishjpJSFとJAX-RSで作る Thin Server Architecture #glassfishjp
JSFとJAX-RSで作る Thin Server Architecture #glassfishjp
 

Similar to ラムダと invokedynamic の蜜月

jvmlang.daitokai 1.0.0 MinCamlJを作ってみた
jvmlang.daitokai 1.0.0 MinCamlJを作ってみたjvmlang.daitokai 1.0.0 MinCamlJを作ってみた
jvmlang.daitokai 1.0.0 MinCamlJを作ってみたKazuyoshi Kamitsukasa
 
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptxTypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptxssuser8b389c
 
jcmd をさわってみよう
jcmd をさわってみようjcmd をさわってみよう
jcmd をさわってみようTsunenaga Hanyuda
 
Springでdao 20070413
Springでdao 20070413Springでdao 20070413
Springでdao 20070413Funato Takashi
 
Java8 lambdas chapter1_2
Java8 lambdas chapter1_2Java8 lambdas chapter1_2
Java8 lambdas chapter1_2yo0824
 
第一回社内 Scala 勉強会(一部抜粋)その 2
第一回社内 Scala 勉強会(一部抜粋)その 2第一回社内 Scala 勉強会(一部抜粋)その 2
第一回社内 Scala 勉強会(一部抜粋)その 2lyrical_logical
 
Adaptive optimization of JIT compiler
Adaptive optimization of JIT compilerAdaptive optimization of JIT compiler
Adaptive optimization of JIT compilernothingcosmos
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageTaku Miyakawa
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Ra Zon
 
DynamoDB Streamを使ったリアルタイム分析
DynamoDB Streamを使ったリアルタイム分析DynamoDB Streamを使ったリアルタイム分析
DynamoDB Streamを使ったリアルタイム分析ShinsukeYokota
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1Ryosuke IWANAGA
 
【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する
【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する
【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化するLIFULL Co., Ltd.
 
18166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi200918166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi2009Muhammad Ali
 
Scalaのimplicit、カリー化
Scalaのimplicit、カリー化Scalaのimplicit、カリー化
Scalaのimplicit、カリー化yuya-nakamura
 
Lumen使ってみたレポ
Lumen使ってみたレポLumen使ってみたレポ
Lumen使ってみたレポmikakane
 

Similar to ラムダと invokedynamic の蜜月 (20)

Spring3.1概要x di
Spring3.1概要x diSpring3.1概要x di
Spring3.1概要x di
 
MoteMote Compiler Plugin
MoteMote Compiler PluginMoteMote Compiler Plugin
MoteMote Compiler Plugin
 
Cve 2013-0422
Cve 2013-0422Cve 2013-0422
Cve 2013-0422
 
jvmlang.daitokai 1.0.0 MinCamlJを作ってみた
jvmlang.daitokai 1.0.0 MinCamlJを作ってみたjvmlang.daitokai 1.0.0 MinCamlJを作ってみた
jvmlang.daitokai 1.0.0 MinCamlJを作ってみた
 
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptxTypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
 
Em synchrony について
Em synchrony についてEm synchrony について
Em synchrony について
 
jcmd をさわってみよう
jcmd をさわってみようjcmd をさわってみよう
jcmd をさわってみよう
 
Springでdao 20070413
Springでdao 20070413Springでdao 20070413
Springでdao 20070413
 
Java8 lambdas chapter1_2
Java8 lambdas chapter1_2Java8 lambdas chapter1_2
Java8 lambdas chapter1_2
 
第一回社内 Scala 勉強会(一部抜粋)その 2
第一回社内 Scala 勉強会(一部抜粋)その 2第一回社内 Scala 勉強会(一部抜粋)その 2
第一回社内 Scala 勉強会(一部抜粋)その 2
 
Adaptive optimization of JIT compiler
Adaptive optimization of JIT compilerAdaptive optimization of JIT compiler
Adaptive optimization of JIT compiler
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]
 
DynamoDB Streamを使ったリアルタイム分析
DynamoDB Streamを使ったリアルタイム分析DynamoDB Streamを使ったリアルタイム分析
DynamoDB Streamを使ったリアルタイム分析
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1
 
【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する
【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する
【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する
 
MongoDB勉強会資料
MongoDB勉強会資料MongoDB勉強会資料
MongoDB勉強会資料
 
18166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi200918166746-NeverBlock-RubyKaigi2009
18166746-NeverBlock-RubyKaigi2009
 
Scalaのimplicit、カリー化
Scalaのimplicit、カリー化Scalaのimplicit、カリー化
Scalaのimplicit、カリー化
 
Lumen使ってみたレポ
Lumen使ってみたレポLumen使ってみたレポ
Lumen使ってみたレポ
 

More from Taku Miyakawa

Java SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にJava SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にTaku Miyakawa
 
Graph Algorithms Part 1
Graph Algorithms Part 1Graph Algorithms Part 1
Graph Algorithms Part 1Taku Miyakawa
 
Matrix Multiplication in Strassen Algorithm
Matrix Multiplication in Strassen AlgorithmMatrix Multiplication in Strassen Algorithm
Matrix Multiplication in Strassen AlgorithmTaku Miyakawa
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Taku Miyakawa
 
擬似乱数生成器の評価
擬似乱数生成器の評価擬似乱数生成器の評価
擬似乱数生成器の評価Taku Miyakawa
 
コルーチンの実装について
コルーチンの実装についてコルーチンの実装について
コルーチンの実装についてTaku Miyakawa
 
言語設計者が意味論を書くときに考えていたこと
言語設計者が意味論を書くときに考えていたこと言語設計者が意味論を書くときに考えていたこと
言語設計者が意味論を書くときに考えていたことTaku Miyakawa
 
金勘定のためのBigDecimalそしてMoney and Currency API
金勘定のためのBigDecimalそしてMoney and Currency API金勘定のためのBigDecimalそしてMoney and Currency API
金勘定のためのBigDecimalそしてMoney and Currency APITaku Miyakawa
 
Quasar: Actor Model and Light Weight Threads on Java
Quasar: Actor Model and Light Weight Threads on JavaQuasar: Actor Model and Light Weight Threads on Java
Quasar: Actor Model and Light Weight Threads on JavaTaku Miyakawa
 
Summary of "Hacking", 0x351-0x354
Summary of "Hacking", 0x351-0x354Summary of "Hacking", 0x351-0x354
Summary of "Hacking", 0x351-0x354Taku Miyakawa
 
Processing LTSV by Apache Pig
Processing LTSV by Apache PigProcessing LTSV by Apache Pig
Processing LTSV by Apache PigTaku Miyakawa
 
Kink: プロトタイプベースの俺々 JVM 言語
Kink: プロトタイプベースの俺々 JVM 言語Kink: プロトタイプベースの俺々 JVM 言語
Kink: プロトタイプベースの俺々 JVM 言語Taku Miyakawa
 
Java オブジェクトの内部構造
Java オブジェクトの内部構造Java オブジェクトの内部構造
Java オブジェクトの内部構造Taku Miyakawa
 
Kink: developing a programming language on the JVM
Kink: developing a programming language on the JVMKink: developing a programming language on the JVM
Kink: developing a programming language on the JVMTaku Miyakawa
 

More from Taku Miyakawa (17)

Java SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にJava SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心に
 
Graph Algorithms Part 1
Graph Algorithms Part 1Graph Algorithms Part 1
Graph Algorithms Part 1
 
Matrix Multiplication in Strassen Algorithm
Matrix Multiplication in Strassen AlgorithmMatrix Multiplication in Strassen Algorithm
Matrix Multiplication in Strassen Algorithm
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
 
擬似乱数生成器の評価
擬似乱数生成器の評価擬似乱数生成器の評価
擬似乱数生成器の評価
 
コルーチンの実装について
コルーチンの実装についてコルーチンの実装について
コルーチンの実装について
 
言語設計者が意味論を書くときに考えていたこと
言語設計者が意味論を書くときに考えていたこと言語設計者が意味論を書くときに考えていたこと
言語設計者が意味論を書くときに考えていたこと
 
金勘定のためのBigDecimalそしてMoney and Currency API
金勘定のためのBigDecimalそしてMoney and Currency API金勘定のためのBigDecimalそしてMoney and Currency API
金勘定のためのBigDecimalそしてMoney and Currency API
 
Quasar: Actor Model and Light Weight Threads on Java
Quasar: Actor Model and Light Weight Threads on JavaQuasar: Actor Model and Light Weight Threads on Java
Quasar: Actor Model and Light Weight Threads on Java
 
Kink の宣伝
Kink の宣伝Kink の宣伝
Kink の宣伝
 
Java Quine Golf
Java Quine GolfJava Quine Golf
Java Quine Golf
 
Summary of "Hacking", 0x351-0x354
Summary of "Hacking", 0x351-0x354Summary of "Hacking", 0x351-0x354
Summary of "Hacking", 0x351-0x354
 
Processing LTSV by Apache Pig
Processing LTSV by Apache PigProcessing LTSV by Apache Pig
Processing LTSV by Apache Pig
 
Kink: プロトタイプベースの俺々 JVM 言語
Kink: プロトタイプベースの俺々 JVM 言語Kink: プロトタイプベースの俺々 JVM 言語
Kink: プロトタイプベースの俺々 JVM 言語
 
Java オブジェクトの内部構造
Java オブジェクトの内部構造Java オブジェクトの内部構造
Java オブジェクトの内部構造
 
Hadoop jobbuilder
Hadoop jobbuilderHadoop jobbuilder
Hadoop jobbuilder
 
Kink: developing a programming language on the JVM
Kink: developing a programming language on the JVMKink: developing a programming language on the JVM
Kink: developing a programming language on the JVM
 

ラムダと invokedynamic の蜜月