静かなる名辞

pythonと読書

【python】pickleの速度を見る

 pickleが遅くて困った経験、ありませんか? 私はありませんが、実際問題としてpickleの速度ってちょっと気になりますよね。
 という訳で、測ってみました。

# coding: UTF-8

import sys
import pickle
import time

import numpy as np

for obj_size in [10,50,100,500,1000,5000]:
    obj = np.random.rand(obj_size,obj_size)
    print("obj:{0}*{0} sizeof {1:.3f}KB".format(obj_size, sys.getsizeof(obj)/1024))
    print("protocol:time size of pickle")
    for protocol in range(5):
        times_list = []
        for _ in range(10):
            start = time.time()
            s = pickle.dumps(obj, protocol)
            end = time.time()
            times_list.append(end-start)
        pickled_size = sys.getsizeof(s)
        print("{0:d}:{1:.6f} picle sizeof {2:.3f}KB".format(protocol, np.array(times_list).mean(),pickled_size/1024))
    print("")

 ベンチマークに使うオブジェクトとしてnumpy配列が適切なのかという問題はこの際置いておきましょう。pickleには複数のプロトコルがあるので、一応ぜんぶテストしています。

 結果。

obj:10*10 sizeof 0.891KB
protocol:time size of pickle
0:0.000040 picle sizeof 1.096KB
1:0.000042 picle sizeof 1.403KB
2:0.000029 picle sizeof 1.396KB
3:0.000043 picle sizeof 0.970KB
4:0.000045 picle sizeof 0.970KB

obj:50*50 sizeof 19.641KB
protocol:time size of pickle
0:0.000113 picle sizeof 20.368KB
1:0.000103 picle sizeof 29.419KB
2:0.000114 picle sizeof 29.412KB
3:0.000057 picle sizeof 19.720KB
4:0.000156 picle sizeof 19.720KB

obj:100*100 sizeof 78.234KB
protocol:time size of pickle
0:0.000324 picle sizeof 80.868KB
1:0.000349 picle sizeof 117.239KB
2:0.000426 picle sizeof 117.232KB
3:0.000070 picle sizeof 78.313KB
4:0.000044 picle sizeof 78.313KB

obj:500*500 sizeof 1953.234KB
protocol:time size of pickle
0:0.008984 picle sizeof 2013.061KB
1:0.012327 picle sizeof 2928.439KB
2:0.012231 picle sizeof 2928.433KB
3:0.001828 picle sizeof 1953.315KB
4:0.001288 picle sizeof 1953.315KB

obj:1000*1000 sizeof 7812.609KB
protocol:time size of pickle
0:0.023527 picle sizeof 8050.787KB
1:0.044265 picle sizeof 11709.073KB
2:0.044566 picle sizeof 11709.066KB
3:0.005720 picle sizeof 7812.690KB
4:0.006633 picle sizeof 7812.690KB

obj:5000*5000 sizeof 195312.609KB
protocol:time size of pickle
0:0.572241 picle sizeof 201280.162KB
1:1.103286 picle sizeof 292737.517KB
2:1.088822 picle sizeof 292737.510KB
3:0.145712 picle sizeof 195312.690KB
4:0.148891 picle sizeof 195312.690KB

 GCとか絡むのでそこまで正確なベンチマークではありませんが、おおよその傾向はわかります。
 200MB近くあるオブジェクトも最速で0.2秒以下の時間で処理できていること、最新のプロトコル4が一番速いことなどがわかります。また、プロトコル1と2はやたら遅いことがわかります。ところで、python2系で使えるのはプロトコル2までらしいのですが、これを見ただけでもpython2を使い続けるのはしんどそうだ、と思います。また、プロトコル0がやたら健闘しているのはちょっと理由がわかりません。とにかく、大きいオブジェクトに対しては倍の速度差なので、python2系でpickleの遅さに困るシチュエーションがあったら、プロトコル0を試してみるべきなのかもしれません。逆に、この数字を見る限りではpickle1,2を積極的に使う理由はない気がするのですが、どうしてこうなってるんでしょうか。