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を積極的に使う理由はない気がするのですが、どうしてこうなってるんでしょうか。