sci

最果て風呂

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スクリプトの中で最初に呼び出す手続名。:executablet にするのがポイントらしい。

実行してみる

速度はどうなんだろう?time コマンドで計測した。だいぶ遅いなぁ。

real  14m21.046s
user  13m56.239s
sys    0m24.411s

メモリ使用量は最大 85.6MB で、25.5MB 程度まで落ちて再び上昇していくのを繰り返していく感じだった。メモリ管理は何も気にしなくて良いみたいだね。しかしどうすれば速くできるんだろう?

課題

辞書へのパスは Go などでやっているように環境変数から得るようにすれば良さそう。速度に関しては「Lisp 系の書き方」を習得しないことにはどうしょうもないね。