2012/07/11
Clojureの選択
Clojureはなぜ遅いのか、という話
JVM言語同士で比べてもやっぱり遅い。
- 起動の遅さが際立っている。これはどうも初期化時にdocstringやその他のメタデータをセットアップするのに時間がかかってるらしい。
- 初期化が終わって実際の処理に入っても遅い。これはimmutableなデータ構造のオーバヘッドらしい。immutableなデータ構造でもアルゴリズムのオーダーをmutableなやつと同じにすることはできるが、定数係数のオーバヘッドはある。
まあ、でもRichはそれは覚悟の上というか、設計上そういう選択 (遅いのはわかってるが 他のメリットを優先) をしたわけだからなあ。比べられる土俵が悪いという気はする。 そうは言っても比べられちゃうのは仕方ないけれど。
Gaucheでは上の2点については速度の方を優先する選択をしている。 util.sparseのsparse vectorはClojureのpersistent vector構造を 参考にしているけどmutableだし、docstringが無い理由のひとつはまさしく 起動時のオーバヘッドを避けるためだ。
どちらの選択も絶対的な良し悪しがあるわけじゃなく、目的によるとしか言えない。
もっともClojureはREPLでなければバッチコンパイルを通せるのだから、 docstringをまとめてひとつのdata領域に押し込めるとかできそうなものだけど、 JVMの制約だったりするんだろうか。ネイティブに落とす感覚だと、 コンパイル時にメタデータをデータ配列に固めちゃって、関数の方にはオフセットを 持たせとけば、実行開始時にデータ配列をmmapするだけなんで一瞬で済むはずだけど。
(Gaucheは静的データに関してはポインタの絶対値を持たせているので、 起動時にld.soがリロケートするオーバヘッドはかかっているはず。こちらは 起動速度と実行速度のトレードオフ。)
Post a comment