Let's start Scheme

2012-09-26

多値を考える

ずっと放置していた問題の一つ。

最近2chのLisp Schemeスレッドで多値が話題に上がっていて、せっかくだし便乗して考えることにした。(意味不明)

Sagittariusでは多値は第1級オブジェクトになっていて、valuesを呼ぶたびにメモリのアロケーションが走る。これは実は実装の手抜きで、
(apply values (iota 10000 1))
のようなコードをとりあえず走らせるための妥協の産物となっている。ちなみに、Gauche 0.9.3とMosh0.2.7ではこのコードはエラーになる。多分Gaucheは0.9.4辺りできっと直されるだろう(希望的観測)

valuesに期待したいことの一つとして、「これ使っておけば処理系はconsicingしない」というのがある(と思う)。そういう意味ではSagittariusはプログラマの期待を裏切っているわけだ。

自分自身、せっかくvalues使うんだしという感もあるので、現状の上限なしを維持しつつある程度は期待を裏切らない実装にしたい。案としては以下のようになるだろう。
  • ある程度割り付けておいて、あふれた分は都度割付
  • 必要になったら割付してそのバッファを再利用。足りなかったら再度割り付け(Racket方式)
一つ目と二つ目のどこに違いがあるのか?というレベルだが、実装レベルでは多少違うはず。一つ目は上限超えた際に常にメモリ割付が発生するが、そもそもvaluesに(こちらが考えた)上限を超える値は渡されないだろうという楽観的な実装になる。二つ目はユーザは常にこちらの想像を超えるものだが、それを見越してある程度の性能を出しておきたいという悲観的実装になる。
正直、一長一短ではあると思うが、二つ目の実装で困りそうなのが、上記の例みたいなことをされた際に10000個のバッファを常に保持する羽目になることだろう。多分、どこかの段階でGCされるような仕組みにしておかないと、不必要なバッファがメモリを食いつぶすなんて事になる。

さて、どうしたものかな。

No comments:

Post a Comment