Let's start Scheme

2012-11-22

キャッシュを考える

ふとQiitaのLisp Reader Macro Advent Calendar 2012のネタを考えているときに思ったこと。

Sagittariusはパフォーマンス(ほぼレスポンスだが)向上のためにライブラリ単位でFASLのようなものを持っている (正確にはライブラリファイル単位だが)。普通にスクリプトを書く分には気にする必要はないのだが、リーダーマクロが絡んでくると多少考える必要が出てくる。たとえば、組み込みの正規表現はリーダーマクロを用いて読み取った場合リテラルオブジェクトとして扱われる。これはその方がパフォーマンスがいいからに他ならない。

ここで、ユーザー定義のオブジェクトを考える(Qiitaに書く予定のネタは文字セットなんだけど)。たとえばCLOSを用いてオブジェクトを作成するが、リーダーマクロでリテラルとしても返せるようにしたとする。そうすると何が起きるか?普通にスクリプトとして使用されるだけなら特に問題はないのだが、ライブラリ内で使用すると話が違ってくる。

現状ではキャッシュ機構はユーザー定義のオブジェクトをキャッシュする方法を暗に知る方法がない。SRFI-4ではユーザー定義のリテラルを返すようにしているが、これは明示的にどうそのオブジェクトをキャッシュするかということをScheme側で制御しているからできるのである。しかし、いちいちそれを書くのが面倒な場合の方が大体多い。

なんとかならないかなぁと思っていたのだが、なんとなく「完全Scheme」で定義されたオブジェクトなら一般的な方法でいけるような気がしてきている。それは、CLOSのオブジェクトは基本スロットの中身さえ保存してしまえば何とでもなるからだ。スロット名と値を保存して、復元時は単にslot-set!でセットしてやる。

ここで、問題になるのは、「キャッシュできない組み込みオブジェクト」だろう。現状でsubrをうまいことキャッシュする方法を思いついていない。また、自由変数を含むクロージャーがスロットに入っていた場合とかも困る。まぁ、あくまでベストエフォートだと言えばいいので、こういったキャッシュ不可能なものが来たら弾いてしまえばいいといえばそうなんだけど。

不安材料の方が多い気もするし、どうしたものか・・・?

No comments:

Post a Comment