現代の「インタプリタ」ってほぼVMコードへのコンパイル+VMでの実行で、よほどナイーブな実装でない限り既にかなり速いです。そのままVMコードへのコンパイルをネイティブコードへのコンパイルにしてもたいして速くならないんですよ。
結局何に時間かかってるかというと実行時の型検査やディスパッチ、アロケーションで、そこを何とかしないといくらネイティブコンパイルしても速くなりません。そのためには:
- 部分的にでも型宣言などを取り入れて静的型付けに寄せる
- コンパイル時解析をうんと頑張って型推論や生存期間解析する
- 実行時にどんなデータが来るかを見てから部分的に最適なコードにコンパイルする(JIT)
みたいな話になります。
今書かれている型宣言無しのコードそのままにコンパイラで速くしました、というのなら2です。これは既に実例があって、StalinというScheme処理系はランタイムライブラリを含めた全プログラム解析を行って関数がどういう引数で呼ばれているかを追跡し、実行時型検査がほとんど無く、また多くの一時オブジェクトをスタックアロケートするコードを吐きます。C言語経由ですが、「人が書いたCより速い」という評判でした。ただ、ちょっとしたプログラムでもコンパイル時間が数十分とかになりました。全プログラム解析はソフトウェアの規模に対して計算量が急速に増えるので、現代の実用的な規模のソフトウェアではコンパイルが終わらないでしょう。
1はわりと流行りの方向ですが、プログラムの書き方自体を今と変える必要があります。特に型宣言のついていない膨大な過去のライブラリにがんばって型をつけてゆかないと、全体的な恩恵が得にくいです。
なので質問者さんが中途半端と言われてる3が実はかなり有望なのです。型宣言がなくても、実行時になれば実データの型がわかります。そこからコンパイルすれば、コンパイル時間のオーバヘッドはありますが、何百万回も実行されるループの中などであればオーバヘッドの影響は目立たなくなります。
尤も、JITでも実行時情報をうまく使いこなすのを書くのにはコストがかかるので、結局はそれで得られる利得とのバランスになります。JavaScriptの性能が急速に上がったのは、ブラウザで活用されるようになって、ライブラリをC++など他の言語で書くという選択肢が無く(色々試みはあったんですが消えていきました)、しかし性能向上によるメリットが非常に大きかったので企業がたくさんリソースをつぎ込んだからです。
Pythonもメリットが認められればそうなってゆくでしょうが、今のところ性能が必要なコンポーネントを別言語で書いておくと
0 コメント:
コメントを投稿