続2・凄い人見つけた

http://code.google.com/p/t216-lisp/にT216 release-1を公開しました。
ダウンロードのzipにすべてが収まっています。ちなみに開発環境はWinXPとBCCです。
(T216 release-1)

ソースが公開されたので、とりあえず簡単に目を通してみました。
気になったところを何点か。
* 関数の評価規則
関数の名前は大域環境からしか探していないようですね。
funcallやapplyのような関数も提供していないようなので、
これでは高階関数が作れなくて不便かも。
* 構造体のパディング

struct cell {
char id;
struct cell *car, *cdr;
};
struct atom {
char id;
char *name, ftype;
struct cell *val;
};
struct num {
char id;
struct num *num;
double val;
};

char型の変数が1~2個入って構造体の大きさが中途半端な大きさになっていますが、
これでは結構無駄な領域が生まれてしまうことになります。
例えば構造体cellは一見9bytesしか必要なさそうですが、実際には12bytes使っている可能性があります。
(詳しくは「構造体 パディング」とか「構造体 アライメント」などでググってください。)
気にしないのあれば、それで問題ありませんが、気にしてみるのも結構楽しいです。
例えば、上記構造体からchar型の変数を取り除くとそれぞれのサイズは、
8bytes, 8bytes, 12bytesとなり、すべて4の倍数となります。
これらの配列の開始地点のアドレスが4の倍数であると仮定すると、
ポインタの持つ値の下位2bitは必ず0になると分かるため、
この箇所に別の情報を持たせることが可能となります。
そうすると、cell, atom, numはそれぞれ4bit, 4bit, 2bitの領域を確保できます。
この領域にうまくデータを詰め込めたら、使用容量を大幅に抑えることが出来ます。
(ただし、その分速度は落ちますがw)
* コンスセルに持たせる情報
上記の構造体の定義から分かるように、
それぞれのオブジェクト自身がその種類を表す情報(id)を持っているようですが、
コンスセルに「参照先の」オブジェクトの種類を持たすという手もあります。
その方がメモリ参照回数が減るなど色々と都合がよくなりますが、
今から修正するのは少々面倒かもしれません。

Leave a Reply