Pythonの変数を一時書き出ししておく「joblib」と「pickle」を徹底的に比較する。
Pythonの変数をそのまま一時保存しておきたい
Pythonのオブジェクトを一時的に保存しおく方法には「csv書き出し」や「pickle」を使うなどの方法があります。
しかし「csvでは読み書きの作業が面倒」「pickleではファイルサイズが大きくなりがち」という問題があります。
そこで「joblib」です。
ここでは「joblib.dump」を使ったリストの書き出しと「joblib.load」を使った読み込みについて解説します。
また「joblib」と「pickle」についてファイルサイズや処理時間などを比較してみたいと思います。
準備
pip install joblib
これだけです。
「joblib」の使用方法
書き出し
import sys sys.setrecursionlimit(10000)#エラー回避 import joblib #保存するリスト test_list=["test","name","job"] #書き出し処理 joblib.dump(test_list, "temp.txt",compress=3)
最初に「RuntimeError: maximum recursion depth exceeded」のエラーを回避するために再帰処理の上限を増やしています。
compress=3
では、圧縮度を設定しています。なお3以上にしてもほぼ変わらない様です。
出力ファイルは圧縮されているので、テキストエディタで開いてみても内容を読み取ることは出来ません。
そこで、読み出す際には「joblib.load」を使用します。
読み出し
import sys sys.setrecursionlimit(10000)#エラー回避 import joblib #読み出し処理 a = joblib.load( "temp.txt") print(a)
読み出しは普通にファイルを指定するだけと非常に単純です。
「pickle」と「joblib」の比較
ファイルサイズの比較
次にpythonで一般的に使われている「pickle」と比較を行ってみたいと思います。
生成コード
import sys sys.setrecursionlimit(10000)#エラー回避 import joblib import pickle import time test_list=[] for i in range(10000000): test_list.append(i) #「joblib」での書き出し joblib.dump(test_list, "temp_joblib.txt",compress=3) #「pickle」での書き出し with open('temp_pickle.txt', 'wb') as f: pickle.dump(test_list, f)
ファイルサイズの結果
「joblib」では14876kb
「pickle」では48720kb
となり、「joblib」は「pickle」と比べて倍以上のファイルサイズ節約ができるという結果になりました。
書き込み速度の比較
「time」を使って保存及び読み出しの際の実行速度も比較してみたいと思います。
import sys sys.setrecursionlimit(10000)#エラー回避 import joblib import pickle import time test_list=[] #読み出し処理 test_list = joblib.load( "temp.txt") t1=time.time() #「joblib」での書き出し処理 joblib.dump(test_list, "temp_joblib.txt",compress=3) t2=time.time() #「pickle」での書き出し with open('temp_pickle.txt', 'wb') as f: pickle.dump(test_list, f) t3=time.time() print("joblib ",str(t2-t1)) print("pickle ",str(t3-t2))
書き込み速度の結果
joblib 34.55282759666443
pickle 0.5858054161071777
(秒単位)
書き込みスピードは「pickle」の方が圧倒的に早いみたいです。
やはり圧縮処理を挟むことで時間はかなりかかってしまうようですね。
追記
10回試行した平均を出したもの
読み込み時間の比較
同じく、読み込み時間を比較してみたいと思います。
import sys sys.setrecursionlimit(10000)#エラー回避 import joblib import pickle import time t1=time.time() #「joblib」での読み込み処理 joblib.load("temp_joblib.txt") t2=time.time() #「pickle」での読み込み処理 with open('temp_pickle.txt', 'rb') as f: a=pickle.load(f) t3=time.time() print("joblib ",str(t2-t1)) print("pickle ",str(t3-t2))
読み込み時間の結果
joblib 17.864126682281494
pickle 0.9516866207122803
(秒単位)
追記
10回試行の平均
比較結果まとめ
ファイルサイズ(joblibの勝ち)
joblib=14876kb
pickle=48720kb
書き込み時間(pickleの勝ち)
joblib 34.55282759666443
pickle 0.5858054161071777
読み込み時間(pickleの勝ち)
joblib 17.864126682281494
pickle 0.9516866207122803
結論
ファイルサイズの観点からみれば「joblib」が優れており、読み書き処理時間の観点では「pickle」の方が格段に早いようです。
なのでファイルサイズが大きくなりがちな変数は「joblib」で管理し、対して大きくないファイルは「pickle」を使用するのが良さそうです。
参考ページ
PythonのPickleモジュールを理解したいだけの人生だった - Qiita
【Python】処理にかかる時間を計測して表示 - Qiita
joblibは、巨大なデータ構造体の配列バッファに対して特別な処理を行うため、大規模で巨大な配列では通常かなり高速です。実装の詳細については、source codeをご覧ください。zlibを使用して酸洗いしながら、そのデータをその場で圧縮することもできます。
python – joblibとpickleの異なるユースケースは何ですか? - コードログ
joblib と pickle の比較 - Tak's Notebook
Python3: 並列処理で速度を上げる Joblib | お名前.com、さくらのVPS等のサーバーでの開発・設定メモ
joblibの真髄は並列処理とのこと。
設定とマシンスペックさえあればかなり高速化できそう。