Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AOT と direct linking

xorphitus
January 26, 2016

AOT と direct linking

Clojure 1.8 の新機能である direct linking の解説です。

xorphitus

January 26, 2016
Tweet

More Decks by xorphitus

Other Decks in Programming

Transcript

  1. Clojure のコンパイル・モデル 新機能 direct linking の前に Clojure のコンパイル (Java バイトコードへの変換)

    は、だいたい2種類 • ソースコードを Clojure の処理系がロードする時に行う ◦ えーと、ここボヤっとしてるんだけど、 JIT ってことなのかなと ◦ ってことは、JVM が JIT しているのでダブル JIT ですね • 先にコンパイルしておいてから処理系に渡す ◦ ahead-of-time compilation (AOT) ◦ direct linking が有効になるのはこっち ※ちなみに、ランタイムにコンパイルを実行する関数も用意されている
  2. JIT vs AOT (Java バイトコードコンパイル時) • JIT の利点 (たぶん) ◦

    動的コンパイルが許されるがゆえの REPL 駆動開発 ◦ プログラムが全て REPL の上に乗るので、実際のプロセスの中に入って改変・実行しながら開発が できる ◦ ところで、REPL 駆動駆動って Haskell 辺りとも相性いいと思うのだがどうだろう • AOT の利点 (公式より転載) ◦ ソースコードなしでアプリケーションを配布できる ◦ アプリケーションの起動速度を向上させられる ◦ Java から呼び出し可能な名前付きクラスを生成できる ◦ ランタイムのバイトコード生成と、カスタムクラスローダのどちらも不要なアプリケーションを作れる
  3. JIT vs AOT 体感してみよう • 実演: REPL 駆動開発および速度比較 ◦ https://github.com/xorphitus/aot-experiments

    • 参考 ◦ http://qiita.com/ayato_p/items/56595ece48837438d97f ◦ というか、ほぼパクっている
  4. direct linking とは 三行で言うと • AOT 時のコンパイルオプションで • 関数実行のオーバーヘッドを小さくできて •

    コードサイズも削減されて起動速度が上がるもの この理解には、まず Clojure の関数実行の仕組みを知る必要がある
  5. direct linking は Var の存在を消す こんなコードがあったとして (defn add [a b]

    (+ a b)) add (λ (+ a b)) シンボル Var 関数 mutable なポインタみたいなもの ポインティング先は immutable 可変ゆえに REPL 駆動開発中は 再定義して動作確認ができる direct linking しない場合は 赤矢印のフローで関数実行される つまり、Var の dereference の コストが発生する direct linking する場合は AOT 時に Var が解決されて 関数実行が青矢印で行われる ついでに不要な Var は一掃され class ファイルは小さくなる
  6. Var の減を確認してみる $ find simple-aot/target/classes/simple_aot -type f | xargs javap

    | grep Var $ find direct-linking/target/classes/direct_linking -type f | xargs javap | grep Var ちなみに消えない Var もある Var は動的スコープを作ることもできて 例えば、スレッド毎に動的スコープを作り、並行処理を行うのに使われる こういう場合は流石に Var を消したらマズいわけで なお、今回残っている Var が何なのかはよく分からn(ry