compact_number_listのパフォーマンス

とりあえずテスト結果の傾向のみメモ。


昨日のcompact_number_listをインデクシングを使ったリスト版とイテレータ版の時間を比較していたが、短いリストだとインデクシングの方が速いが、長いリストになるとイテレータの方が速い。compact_number_listではchainとteeがボトルネックになっていて特にchainが遅い。Python3.0では2.5よりもchainは少し速くなっていて、chainの代わりにzip_longestも使えるがchainとほぼ同等の速度だった。


扱うリストが長ければイテレータの方が有利になってくるという傾向は一般的なように思える。

Python 3.0のrangeの注意点

Python 3.0をテストしていて驚いたのが以下の例。

>>> from timeit import *
>>> t1 = Timer('L[5000]', 'L=range(10000)')
>>> t2 = Timer('L[5000]', 'L=list(range(10000))')
>>> t1.timeit()
0.61441663675145719
>>> t2.timeit()
0.1539030798605836

3.0のrangeは2.5のxrangeを意味する。2.5でもxrangeで生成したオブジェクトに対してインデクシングできたのは意識していなかったが、rangeはイテレータっぽいものだと思うのでインデクシングは遅いと思われる。ちなみに、L=range(10)としてnext(L)とすると、「TypeError: range object is not an iterator」とエラーが出るのでイテレータではないらしい。


3.0ではリストを返すrangeがなくなるので、リストのような感覚でrangeを使用していると効率の悪いコードができてしまう。例えば関数の引数でイテレータでなくリストを受け取ることを想定して実装してインデクシングなどを使用していると、rangeオブジェクトが渡された際にパフォーマンスの悪いコードになってしまう。そういう場合はlist化してから渡す必要があるかもしれないが、恐らくリストのサイズやインデクシングの回数によってはlist化するオーバーヘッドの方がより時間がかかるかもしれない。


以下に3.0のrangeでできることをまとめる。挙動としては限定的なリストっぽい。2.5と3.0で挙動は共通。

list range イテレータ
L[1] OK OK NG
L[1:3] OK NG NG
len(L) OK OK NG
next(L) NG NG OK


あと大事なポイントとしては、2.5のxrangeはint値しかとれなかったが、3.0のrangeはlong値(に2.5で相当するもの)を引数にとれるようになった。確か、3.0でのintは2.5のlongにあたり、2.5のintにあたるものは3.0ではなくなったと思う。

UMPC

小さくて安いノートパソコンがあると聞いていたがUMPC(ウルトラモバイルPC)というのか。エイサー社のAspireone AOA150-Bwが価格comで46,200円だったけど、3万円切るくらいになったら携帯電話感覚でセカンドPCとして買おうかな。しかし解像度が1024×600しかないので狭くて仕事用のアプリが使えなさそうなので、単なる娯楽用になってしまうかも。

tkinter

Python 3.0でTkinterモジュールが標準ライブラリからドロップしたと思ったら、tkinterモジュールに名前が変更されているだけだった。Pyhon以外何もインストールしなくても使えるのでやはりwxPythonよりも手軽。


しかし、Tkinter調べていたらドラッグ&ドロップは外部ライブラリをインストールしないといけないらしい。複雑なことをやろうとするとTkinterは情報も少なく面倒なので、GUIwxPythonでやることにした。また勉強を再開するつもり。


他にCPythonと簡単に連携できるGUIを作れるやつないかな?GroovyもCPythonとの連携もいまいちだろうし。