Archive for 2月, 2011

リリカルLispの起動が速くなりました

金曜日, 2月 18th, 2011

リリカルLisp ver1.4を公開しました。
今回の主な変更点は起動の高速化です。
結論から言うと、ver1.4はver1.3より約2.5倍も起動が速くなりました。

一見凄いことをしたように見えますが、
元のコードがシンボル生成の際にメモリを無駄に舐め回す、
アホな作りになっていただけ。ごめんなさい。
そこを普通のコード(?)に変えるだけで馬鹿みたいに速くなりました。

実は、その箇所を変更した時点で起動時間はver1.3の約9倍速くなりました。
しかし、「起動が速すぎてリリカルLispらしくない」という思いから、
なんとか起動時間を引き伸ばせないかと考え、

ver1.3以前ではフリーモードでしか使えなかった関数を、
どこでも使えるように修正しました。

フリーモードでしか使えなかった関数というのは、ここのcaar以下の関数です。
これらの関数はSchemeで書いてあり
使うためにはまずそれらの定義を評価する必要がありますが、
残念なことに、それらの評価にはそれなりに時間がかかってしまいます。

ということで、ver1.3以前は起動時間のさらなる増加を避けるため、
起動時にはそれらの関数定義の評価を行わず、
フリーモードを動かしたときに評価を行うようにしていました。
しかし、今回起動時間が速くなったので、
ver1.4では起動時にこれらの関数定義の評価を行うよう変更しました。

これにより、起動時間が延びて安心
以前より多く関数が本編で使えるようになり便利になったはずです。

私の手元での起動時間 (10回計測の中間値)

ver1.3 (シンボルの生成でアホなことをしていた) 4657ms
未公開版 (シンボルの生成のコードを修正) 515ms
ver1.4 (関数定義を起動時に行う) 1825ms

また、地味な変更点として、シンボルのもつ文字列に対するGCの追加があります。
ver1.3以前では、シンボルを一度つくると、それの文字列は、
シンボル自体が回収されても放置されていたのですが、
今回、Copying GCでそれを回収するようにしました。
(Copying GCにしたのは、もとの実装を極力変更したくなかったため)
今のところシンボルを生成するような関数 (string->symbolなど) は提供していないので、
恐らくこのGCが呼ばれることはないでしょうが。

新・ニコ動でLisp

土曜日, 2月 12th, 2011

また作りました。

コメントにあるとおり、ニワン語(ニコニコ動画上のスクリプト言語)の仕様変更のため、
以前作ったものがまともに動かなくなってしまいました。
なんとか動くようにと頑張ってみたんですが、途中で力尽き、
「これはもう、一から作り直したほうが早いんじゃないのか?」
と思い、作り直したという流れです。

ニワン語もいつの間にか使いやすくなったもので、
たったの50行ほどで書けてしまいました(ソースはこちらから)。
しかし、相変わらずよく分からない挙動をすることがあり、苦労します。
今回、ダイナミックスコープになっているのは、その妙な挙動に悩まされたためです。
最初はレキシカルスコープでつくっていたんですが、
環境の書き換えを(配列を破壊的に書き換えることにより実現)するところで、
何故か変数が壊れたり変な動作をしたり、変な動作をするようになりました。
私のプログラムが悪いのじゃないかと思い、
数時間に渡るデバッグをしたものの原因は分からず。
配列の書き換えを避けるためにダイナミックスコープにしたという訳です。
(変数の参照先は書き換えるが、配列自体は書き換えない。ソース中のgenvを参照)
スコープ以外の仕様は以前のものとほぼ同じです。

**NewNicoLisp 仕様**
<サポートする関数>
car
cdr
cons
eq (数の比較もこれで行う)
atom
+ (引数は任意個)
– (引数は2つ)
eval
<サポートするスペシャルオペレータ>
quote
if
progn
lambda
defun
<データ>
シンボル (日本語なども使用可能)
数 (入力時は非負整数のみ)
コンス (今のところはimmutable)
その他 (SUBR、FSUBR、EXPR)
<リーダ>
quoteのリーダマクロあり
ドット記法の入力は未対応
<スコープルール>
ダイナミックスコープ