Pythonのデータのキャッシュ保存モジュール比較【備忘録】

お疲れ様です。

Pythonにはオブジェクトをキャッシュデータとしてファイル保存するモジュールがいくつかあります。 今回はそれらのモジュールをそれぞれ使用して比較してみたという内容です。

コードはこちらに残してあります。 github.com

  • 今回使用するデータについて

データについては、私が個人的に使用しているChatGPTからエクスポートした履歴データを使用しています。 このうちのチャット履歴データのjsonファイル(conversations.json)を読み込んで、このデータをキャッシュとして保存して比較しています。
ChatGPTの履歴のエクスポートについてはこちらが参考になると思います。
https://www.goatman.co.jp/media/chatgpt-export-data/

実際に使用するデータはこちらになります。 json



pickle

docs.python.org
Pythonの標準モジュールで、Pythonオブジェクトの保存では一番よく見るモジュールかなと思います。 有名なところだとPytorchのモデル保存(torch.save)でも使われています。
データをバイト列に変換してファイル保存(シリアライズ)します。

import pickle

# 保存
with open("conversations_cache.pickle", mode='wb') as f:
    pickle.dump(data, f)

# 読み込み
with open("conversations_cache.pickle", mode='rb') as f:
    data = pickle.load(f)

実際に保存したデータは以下になります。 元のjsonファイルと比較してもファイルサイズが小さくなっていることがわかります。 (1486KB -> 876KB) pickle

実行時間はこんな感じ。

  • 保存: 3.16 ms

  • 読み込み: 6.12 ms

shelve

docs.python.org Pythonの標準モジュールで辞書形式でデータを格納して保存するイメージです。 簡易的なデータベースとしても扱えます。 ちなみに、内部的にはpickleが使われているようです。

import shelve

# 保存
with shelve.open("conversations_cache.shelve") as db:
    db['data'] = data

# 読み込み
with shelve.open("conversations_cache.shelve") as db:
    data = db['data']

他とは違い3つのデータが保存されます。 .datのデータがpickleのファイルサイズと同じですね。 shelve

実行時間はこんな感じ。 pickleの処理+shelve特有の処理で多少実行時間が伸びている感じでしょうか。

  • 保存: 8.94 ms

  • 読み込み: 26.1 ms

joblib

joblib.readthedocs.io 一般的には処理の並列化に使われるライブラリですが、シリアライズの機能も持っています。 joblibのシリアライズは他と違いデータの圧縮の機能もあります。 下記コードのdumpの引数compressで圧縮率を設定できます。

こちらはサードパーティライブラリなのでpip等で個別にインストールする必要があります。

pip install joblib

import joblib

# 保存
joblib.dump(data, "conversations_cache.joblib", compress=3)

# 読み込み
data = joblib.load("conversations_cache.joblib")

出力ファイルが以下になります。 圧縮しているのでファイルサイズは他と比べても小さくなっていますね。 joblib

実行時間はこんな感じ。 処理時間については他のモジュールと比べて明確に遅いですね。

  • 保存: 92.0 ms

  • 読み込み: 44.2 ms

cloudpickle

github.com 基本機能はpickleと同じですが、関数やクラスなどpickleでは扱えないオブジェクトについても保存できます。

こちらもサードパーティライブラリなのでpip等で個別にインストールする必要があります。

pip install cloudpickle

import cloudpickle

# 保存
with open("conversations_cache.cloudpickle", mode='wb') as f:
    cloudpickle.dump(data, f)

# 読み込み
with open("conversations_cache.cloudpickle", mode='rb') as f:
    data = cloudpickle.load(f)

出力されたファイルが以下になります。 保存したのが同じデータなので容量的にもpickleとも変わらないですね。
cloudpickle

実行時間はこんな感じ。 今回のデータと環境では、保存はpickleと大差なく、読み込みはこちらの方が速いという結果でした。 ただ、一般的にはpickleの拡張ということもあってcloudpickleの方がやや遅いらしいです。

  • 保存: 2.99 ms

  • 読み込み: 3.42 ms

比較まとめ

最後に結果をまとめました。 実行時間については何度か実行しましたが結構ばらつきがあったので参考程度に。

元データ(json) 1486KB

モジュール サイズ[KB] 保存[ms] 読み込み[ms]
pickle 876 3.16 6.12
shelve 876 8.94 26.1
joblib 250 92.0 44.2
cloudpickle 876 2.99 3.42

今回4種試した中で個人的にはjoblibが一番いいかなと思いました。やっぱり圧縮機能が便利。