Island Life

< 100年後の言語 | 多バイト文字とDFA >

2008/09/04

v8とかスクリプトとか

lucille development blog - V8 benchmarked

py2llvm の経験から、スクリプト言語はネイティブの 100 ~ 1000 倍遅く、JIT したとしても数十 ~ 100 倍くらい遅いもんだと思ってました.

[...]

もはやあと数年もしたら、動的言語やスクリプト言語が、ネイティブ版とほぼ変わらないくらいの速度で実行できるほどに JIT 技術が進化しそうだ.

「スクリプト言語」の定義が曖昧なので厳密な議論にはならないのだ けれど、大島さんも書いているように 動的言語であるCommon Lispはon-the-flyでコンパイルして Cにほぼ匹敵する速度(*)も可能だったわけで、何が足を引っ張っていたかというと 単に実装者がさぼっていただけだと思うなあ。

もちろんここでの「さぼる」は悪い意味じゃなくて、工学はトレードオフなので、 そこに手間をかけるよりも優先度が高いところがあったってことだ。 特にネイティブコードでがりがり最適化をかけるような話は開発リソースを 喰うので、開発リソースがscarceな状況で手を出すのは得策ではない。 従って、Googleみたいにリソースをつぎ込めるところが手を出してくれるのは 有難いことである。

C++が速い、というが、その速さの源は言語そのもののの性質だけではなく、 コンパイラベンダが巨大な開発リソースをつぎ込み、プロセッサ メーカもそれに合わせたアーキテクチャを作ってるってところが大きいと思う。 一般の開発者は、その成果に乗っかる形でコードを書いているわけだ。 ある意味、分業による効率化とも言える。

Clojureを作ったRich Hickeyは、 「VM、GC、JIT、OSインタフェースなどはリソースのあるところにまかせて、 言語開発者はもっと上の方の言語デザインに力を割くべき」みたいな ことを言っていた (ClojureはJVM上で走る)。

その見方をとれば、Googleがリソースをつぎ込んで爆速JavaScript実装を 広めてくれれば、「JavaScriptへとコンパイルして後はJavaScript処理系に 任せる」という方針はぐっと現実味を帯びてくる。 BiwaSchemeとか、 時代を先取りしてたかもね。

いずれにせよ、速い実装がポピュラーになれば既存の実装への プレッシャーになることは間違いなく、 Gaucheでもますます 色々試してみたい時代になってきた。

(* Cコンパイラもナイーブだった頃。global analisysをやるような最適化 コンパイラに対しては、ローカルな情報しか使えないインクリメンタルコンパイルは 負けるだろう。ただ、開発中のインクリメンタルなモードではコンパイル速度を重視し、 アプリが完成したらバッチでコンパイルするといった複数のモードをつけられない 理由はない)

そうそう、 http://d.hatena.ne.jp/squeaker/20080904 :

高速化のためには数値型や文字列に関する仮定は置かなくてはならないので、 例外なしに完全にできるわけではないですが、四則演算みたいなものの 定義は書き換えたら遅くなっちゃうけど、それら以外は別にIntegerやStringであっても 少々変えても大丈夫、というようなものにはできると思います。

Lispのネイティブ実装は、例えば加算ならデフォルトのfixnum additionのコードを 吐いておいて、オペランドがfixnumでなかった場合はtype error例外が飛ぶので それを捕まえてより複雑な加算処理を行う、みたいなのがよく使われてたと思う。 この方式だと加算の意味を後から追加していっても、多くのケースで性能は犠牲にならない。 ただこれはハードウェア命令がタグチェック→例外をサポートしてくれてる ことが大きいんで、現代のプロセッサでタグチェックを一般命令で挿入すると どのくらいアドバンテージが出るかはわからない。

Tags: Programming, Lisp