sbcl 実行バイナリの作り方
実行ファイルを作成するのにはまる
今までずっと sbcl --script hoge.lisp
のような使い方をしていたのだけれど、「実行バイナリにすると速くなるよ!」とのことなので挑戦してみることにした。
記事に書いてある通りにやってみたのだが、ファイルを load
する初っ端でエラーになってしまった。どうやらシェバングがあると駄目みたいだね。で、その行を削除してやってみると実行ファイルが作成された。
しかしいざ起動してみると「スクリプトから外部に参照している辞書ファイルが見付からないよ」というエラー。どうやらパスがおかしくなっているみたいだ。自分は下記のように参照する辞書をスクリプト自身からの相対パスで指定しているのだが、これがいけないみたい。
(defparameter *scriptname* cl:*load-truename*) (defparameter *mtorootdir* (cl-ppcre:regex-replace "mto-sbcl.lisp" (namestring *scriptname*) "")) (defparameter *kana-jisyo* (concatenate 'string *mtorootdir* "../dict/kana-jisyo")) (defparameter *kanji-jisyo* (concatenate 'string *mtorootdir* "../dict/kanji-jisyo"))
試行錯誤の結果、以下のようにすればちゃんと動く実行ファイルが作成された。繰り返すけど、あらかじめシェバングの行は削除しておくこと。mto/tool/
内で
> sbcl * (load "mto-sbcl.lisp") * (save-lisp-and-die "mto-sbcl" :toplevel 'main :executable t)
mto-sbcl
は実行ファイルの名前。:toplevel
はスクリプトの中で最初に呼び出す手続名。:executable
を t
にするのがポイントらしい。
実行してみる
速度はどうなんだろう?time
コマンドで計測した。だいぶ遅いなぁ。
real 14m21.046s
user 13m56.239s
sys 0m24.411s
メモリ使用量は最大 85.6MB で、25.5MB 程度まで落ちて再び上昇していくのを繰り返していく感じだった。メモリ管理は何も気にしなくて良いみたいだね。しかしどうすれば速くできるんだろう?
課題
辞書へのパスは Go などでやっているように環境変数から得るようにすれば良さそう。速度に関しては「Lisp 系の書き方」を習得しないことにはどうしょうもないね。