JavaのLambdaの裏事情
Upcoming SlideShare
Loading in...5
×
 

JavaのLambdaの裏事情

on

  • 4,118 views

ぷろぐぱ ~プログラミング言語のパフォーマンスを考える~

ぷろぐぱ ~プログラミング言語のパフォーマンスを考える~
2013/12/7 福岡
でのプレゼン資料

Statistics

Views

Total Views
4,118
Views on SlideShare
4,066
Embed Views
52

Actions

Likes
14
Downloads
16
Comments
0

1 Embed 52

https://twitter.com 52

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

JavaのLambdaの裏事情 Presentation Transcript

  • 1. JavaのLambdaの裏事情 ぷろぐぱ ~プログラミング言語のパフォーマンスを考える~ 2013/12/7 きしだ なおき @kis
  • 2. プログラミング言語が動くまで ● 字句解析 – ● 構文解析 – ● 構成要素がどの構文要素か解析 実行エンジン – ● 文字が言語どの構成要素か解析 コンパイル言語の場合は実行ファイルを生成 CPU – 実際に計算を行う
  • 3. 言語の構文がパフォーマンスに影響 ● ● 動的型付言語は静的型付言語より遅い JavaScriptの配列は遅い – ● インデックスが連続してなくてもいいため (という傾向がある)
  • 4. とはいえ ● ● ● 動的型付言語も速くしたい 静的型付言語も便利にしたら遅くなる みんないろいろ工夫する
  • 5. 主な戦略 ● ● だいたい難しいことしない よくある処理が速くなると全体的に速くなる
  • 6. ということでJavaの場合
  • 7. Java言語とは ● ● 静的型付 オブジェクト指向 – ● 事前コンパイル型 – ● というかクラス指向 Java VM用バイナリを生成 Java VMで動く
  • 8. 実はJava-Javaコンパイラ ● 文字列でのswitch ● 匿名クラス
  • 9. 文字列でのswitch public static void main(String[] args) { switch(args[0]){ case "a": System.out.println("えー"); break; case "b": System.out.println("びー"); break; } } public static void main(String[] args) { String str = args[0]; int h = str.hashCode(); int c = 2; switch(h){ case 97: if(str.equals("a")) c = 0; break; case 98: if(str.equals("b")) c = 1; break; } switch(c){ case 0: System.out.println("えー"); break; case 1: System.out.println("びー"); break; } }
  • 10. 匿名クラス public static void main(String[] args) { List<String> strs = Arrays.asList("a","b","c"); strs.sort(new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.compareTo(o1); } }); System.out.println(strs); } public static void main(String[] args) { List<String> strs = Arrays.asList("a","b","c"); strs.sort(new Anonymous$1()); System.out.println(strs); } private static class Anonymous$1 implements Comparator<String> { @Override public int compare(String o1, String o2) { return o2.compareTo(o1); } }
  • 11. Javaの最適化 ● Java VMががんばる – JITなど ● ● ● ネイティブコードに実行時にコンパイル Java VMががんばれるコードをコンパイラが生成す る Java VMががんばりやすい構文にする
  • 12. JVMはJava言語だけのものじゃない ● 動的型 – – Clojure – JavaScript – ● JRuby Jython 静的型 – Scala
  • 13. ところで圧倒的に動的型! ● Javaがそれなりに使えるので他の静的型言語が使 われにくい – ● ● より強力な型じゃないと意味がない JavaVMにクセがあるので言語仕様で考慮しないと 型の威力がでにくい ※未検証なので水島さんからツッコミがあると思い ます
  • 14. Java VMのメソッド呼び出し (Java SE 6まで) ● invoke static – – – ● invoke special – – – ● コンストラクタやprivateメソッド 常に同じものを呼び出す レシーバー必要(以降同様) invoke virtual – – ● staticメソッド 常に同じものを呼び出す レシーバー(呼び出しオブジェクト)不要 クラスのインスタンスメソッド オブジェクトの型によってメソッドが異なる invoke interface – – インタフェースのインスタンスメソッド オブジェクトの型によってメソッドが異なる
  • 15. 動的型には不向きだった ● ● Java VMはJava言語特化 動的型言語では呼び出しメソッドがコンパイル時に 決めにくい – – リフレクションの利用 Java VMに頼らないメソッド呼び出し
  • 16. Java SE 7で導入された invoke dynamic ● ● 動的型言語のため 実行時にメソッドの型を決めつつJava VMの最適化 もかけやすくする
  • 17. invoke dynamicの仕組み ● ブートストラップ – 実際に呼び出すメソッドを探す 呼び出すメソッドを指すMethodHandleを生成 – MethodHandleをCallSiteにくるんで返す – ● ● ● CallSiteにくるまれたMethodHandleが指すメソッドを呼び 出す 2回目はブートストラップを呼び出さない 呼び出し先が変わったらCallSiteが新たなMethodHandle を返す
  • 18. ところでJavaにLambdaが来たよ ● (int a, int b) -> { return a + b; } ● いろいろ省略できる – (a, b) -> a + b;
  • 19. 関数型インタフェース ● 実装すべきメソッドがひとつのインタフェース – Runnable ( runメソッド) – Comparator( compareメソッド)
  • 20. Lambda式 ● Lambdaは関数型インタフェースを実装するクラスの インスタンスを生成するための構文 Comparator<String> comp = new Comparator<String>(){ @Override public int compare(String o1, String o2) { return o2.compareTo(o1); } }; Comparator<String> comp = (o1, o2) -> o2.compareTo(o1); すっきり!
  • 21. Lambdaの裏側 ● ● ● クラスができていない メソッドができている InvokeDynamic
  • 22. なぜ匿名クラスじゃないのか ● クラスができまくる – – ● Streamなど使うとたくさんクラスができる しかもあまり使われない いちいちコンストラクタをよびだす
  • 23. どのようにInvodeDynamicが使われるか ● ラムダオブジェクトの生成 – – LambdaMetaFactory.metafactory 関数型インタフェースを実装したクラスのインスタンスを生成す るメソッドが返される ● – ● ついでにクラスもこの時点で作ったりする そのメソッドを呼び出してラムダオブジェクトを生成 VMが変わるとより最適化されたインスタンスが生成され る – – 例:メソッドハンドルをラップする共通クラスのインスタンス 例:同じ式には同じインスタンス
  • 24. 結び ● ● ● 言語を実行するためにいろいろがんばってる InvokeDynamicは言語要素の最適な実装をあとま わしにできるおもしろい仕組み わかると楽しい
  • 25. 資料 ● 「Lambda: A Peek Under The Hood - Brian Goetz」 – ● 「ラムダと invokedynamic の蜜月」 – ● http://www.slideshare.net/jaxlondon2012/lambda-a-peekunder-the-hood-brian-goetz http://www.slideshare.net/miyakawataku/lambda-meetsinvokedynamic 「Java 7 invokedynamic の概要」 – http://www.slideshare.net/miyakawataku/java-7invokedynamic-in-a-nutshell