柴田さんがPython3.0の紹介を記事に書いて下さっています。僕も昨日、念願のCodePlexデビューをしたので、新しいバージョンは気になります。Python3.0でも動くようにしたいですし!
で、手近なところで、dictの変更について気になったので調べてみました。できることならばPython2.Xと3.0で一緒に動くプログラムにできたらいいな、という目論見があったので。要素数を10〜300,000ぐらまで変化させながら、データ取得の時間を計ってみました。取得する要素はランダムなstrです。取得するデータはkeyとvalueの両方です。結果は以下の通り。かかった時間を相対的にしてみました。
- Python2.5のiteritems(): 1
- Python2.5のinで回して[]でvalue取得: 1.4
- Python2.5のitems(): 10
- Python3.0a2のitems(): 1.6
- Python3.0a2のinで回して[]でvalue取得: 2.7
Python3.0は「まだちょっと遅いよ」と書いてあったので、だいたいこんなものかな、という速度です。iteritems()はなくなってしまうので、inで回す、というのが一番妥当かな、というのがベンチマークの結果ですね。とりあえず、Python3.0の方のitems()のコードだけ晒しておきます。データはあらかじめ作っておいて、pickleしておいたものを利用しています。
import time import pickle class StopWatch: def __init__(self): self.start_time = 0.0 def start(self): self.start_time = time.time() def stop(self): return time.time() - self.start_time def test(): stopwatch = StopWatch() samples = pickle.load(open("testdata.txt", "br"), ) # samplesには長さが10〜300,000までの辞書が配列に入っています。 for sample in samples: stopwatch.start() for key, value in sample.items(): pass result = stopwatch.stop() print(len(sample), result) if __name__ == "__main__": test()
ここまでやってから、冷静に考えてみると、新スタイルのクラス宣言がデフォルトになって、クラス宣言のところが変わってしまうので、共用コードという作戦はそもそも成り立たないかも。ま、でもベンチマークを取ってみると現実の姿が良く見えて勉強になるね。それ以外に気になったこともメモしておきます。
- エンコードに厳しくなったのでpickleを使うのがちょい面倒
- pickleがやたら遅い。protocol=0のせい?明日測定してみよう
- sys.stdout.write()関数が、出力した文字数をreturnするようになった