2005年02月10日

list関数

可変個の引数の取り方がわからんとかいって,list関数作れねえとかいってたけど西尾氏の助言により何とか成功.

PyObject* PyTuple_GetItem( PyObject *p, int pos) と
int PyTuple_GET_SIZE( PyObject *p)
を使うだけだった.そっから手間取ったのはむしろCレベルの話だったり(ぉ
ちなみに,使い方はこんな感じ.

>>> x=cons.list(1, 2,3)
>>> str(x)
'(1 (2 (3 None)))'

まあ,この調子で組み込み関数を増やしていけばそれなりに使えるものに・・・なるかなあ.
GCに対する処理が今のところお粗末なんだよなあ...カウンタ操作一応書いてるけど,むしろ書かないほうがいいレベルだしなあ...(マーク&スイープが起こらないとリークはするけどごみじゃないオブジェクトが回収されることはない)
後,循環構造に対してなんも考えてなかった.その辺も考慮せんとな・・・

投稿者 reli : 02:19 | コメント (0) | トラックバック

Pythonでconsセル

C言語でPythonを拡張する機能を使って,consモジュールを作ってみた.
とりあえず,Consオブジェクトがもっているのはcar,cdrのみ.__str__はリストの中身を表示してくれる.
consモジュールの関数としては,consセルかどうかを調べるisPair(Object)がある.

実装したソース
後は,setup.py用意してpython setup.py buildとかやればconsモジュールの完成.(setup.pyに関しては割愛)

実際に次のようなソース(下にかいているのは一部)で使ってみた.

for v in [1000, 10000, 100000, 1000000]:
r = range(v)
tmp=0
t=clock()
reduce(add, r)
print clock() - t

r = make_list(v)
tmp = 0
t=clock()
fold(add, r)
print clock() -t


実行結果は,次のとおり

1000 10000 100000 1000000
0.0 0.0 0.01 0.02
0.05 0.16 0.64 1.67
zsh: 1964 segmentation fault python cons.py

ダメじゃん.実行に時間かかる前に多分解放処理で落ちるし・・・.多分GCだろうなあ.1000000のオブジェクトの時だけ落ちるんだよなあ.参照カウンタ方式なのに落ちるって事はどういうことだ・・・.すぐに解放されるなら,1000個の時でも落ちるだろうし.ってことは,すぐに解放しないようにZCTかなんか使ってるのか.それともマーク&スイープでこけてんのか?前者なら増やし忘れとかだろうなあ.マーク&スイープはdeterministicじゃないけど,1000000の時だけ落ちるってのはヒープサイズとかの都合でありなのか?でも,マーク&スイープってCで書いたミスで生まれるようなもんなのか・・・?
とりあえず,適当に書いたけど,もうちょい解析が必要だなあ.(そもそも適当に作ったままだし.)

実行時間が大負けな理由としては,そりゃconsだと遅いだろw
っていうのと,こっちは畳み込み関数が組み込みじゃないので,その辺組み込めば何とかもうちょい押さえれるかもなあ.

まあ,実は今のままじゃリスト生成がめんどいのでlist関数作ろうと思ったけど可変個の引数が渡せなくて断念.なんか,もうちょい全体的に使いやすくなるいい方法はないんだろうか.(バグ直しが先決か)

やはり,落ちる原因は参照カウンタまわりが原因っぽい.カウンタ減らさんようにしたら落ちなくなったし.まあ,多分増やし忘れだろう.
とりあえず,リークするけどほっとくかw

投稿者 reli : 00:22 | コメント (0) | トラックバック