memo

ちょっとしたメモ書き(個別表示)

Gaucheモジュールのプリコンパイル : (2008/01/19)
Gauche用のモジュールのロード時間をプリコンパイルによって短縮する話です。

CGIスクリプトをSchemeで書いてGaucheで実行する場合、小規模なものならともかく、ある程度コード量が増えてくると、実行前のオーバーヘッドが気になるかもしれません。

根本的な解決方法としては、リクエストごとにプロセス起動をやめることですが、
(fastcgiで動作させるなり、Schemeでサーバを書いて常駐させるなり)
あくまでCGIスクリプトとして動作させる場合はモジュールのロードにかかるコストが無視できないものになります。

これを緩和するために、Gaucheにはgencompというスクリプトが付属しています。
どういうものかというと、Schemeのコードを解釈し、Gaucheの内部表現をCのコードで記述した物へと変換する一種のトランスレータです。
(内部表現はバイトコードのようなものですが厳密には違うそうです)
これとCコンパイラと組み合わせればネイティブコードが作成できますが、一般にネイティブコンパイラと呼ばれるものとはかなり毛色が違います。
この仕組みは一部のsrfiなど、利用頻度の高いモジュールのロードのコスト削減に利用されています。

gencompは通常はインストールされないので、Gaucheのソースパッケージから持ってきてください。
以下にversion 0.8.12の場合の使い方を書いておきます。
特に公式なドキュメントがある機能でもないので、この手順は今後変更される可能性がありますので注意してください。


src/example-module.scm
(define-module
example-module
(export func))
(select-module example-module)

(define
func
(lambda (x) (* x x)))

(provide "example-module")

# 手順1
# これでexample-module_head.c, example-module_tail.c
# というファイルが作られます
gauche-config --fixup-extension example-module

# 手順2
# これでexample-module.scm, example-module-lib.c
# というファイルが作られます
gosh -I. gencomp --ext-module example-module.scm \
-o example-module-lib src/example-module.scm

# 手順3
# example-module-lib.soというファイルが作られます
# $GOSH_SRC_PATHはGaucheのソースパッケージの
# srcディレクトリの置いてあるパスを指定してください
# (gauche/macro.hが必要であるためです)
gcc -o example-module-lib.so --shared \
`gauche-config -I` \
-I $GOSH_SRC_PATH example-module-lib.c \
example-module_head.c example-module_tail.c

あとは手順2で生成したexample-module.scmと
手順3で生成したexample-module-lib.soをロード可能な場所に置き
実行するだけです。
以下のサンプルを上記ファイルと同じ場所に置き、
gosh -I . sample.scm
と入力してみてください。
「900」と出力されれば成功です。

sample.scm
(use example-module)
(display (func 30))
(newline)

: back