kiyokaのブログアーカイブ

Archive of old blog posts

初期化スクリプトをコンパイル済にして高速化した

私がRubyで書いているLisp方言、 [Nendo]について。

[Nendo]にはinit.nndという起動直後に読み込まれる初期化スクリプトがある。 中身は[Nendo]のソースコードで、caar や caaar や let1、cond、caseなどの基本的な構文が定義してある。 0.2.0の時点で約600行のソースだ。

このファイルの読み込みが重いという問題があったのだが、かなりad-hocな方法で解決した。 [Nendo]の処理系はもともと Nendo(Lisp言語)を読み込むと、それと等価なRubyコードにトランスレートして実行する仕組みを持っている。 今回 init.nnd の読み込みが重いのは、パース、マクロ展開、Rubyコードへのトランスレートという非常に重いプロセスが済んだ init.nndc(コンパイル済ファイル)というファイルを生成するようにした。(拡張子のネーミングは Emacsの .el と .elc と同様にUNIXで一般的なルールです) 察しの通り init.nndc は生成したRubyコードが入っている。

さて、どれくらいの差があるか計測してみよう。 計測に使ったマシンは PowerBook G4 (PowerPC 1GHz) の非常に時代遅れなマシン。

ちなみに nop.nnd は中身がコメントのみで関数呼び出しも何もないファイル。

;;-*- mode: nendo; syntax: scheme -*-;;
;; Nothing to do.
  • init.nnd (コンパイルなし) ``` bash-3.2$ time nendo nop.nnd

real 0m10.462s user 0m9.550s sys 0m0.280s


- init.nndc (コンパイル済)

bash-3.2$ time nendo nop.nnd

real 0m0.809s user 0m0.636s sys 0m0.110s ```

コンパイルしないと、起動に10秒もかかってしまってしまう。 最初に[Nendo]をさわった人はここで見向きもしなくなるだろうが、コンパイル済であれば、まあギリギリOKの範囲だろう。 0.2.0のリリース版は自動的にコンパイル済の初期化スクリプトが選択されるようになっていますので御安心を。