web-dev-qa-db-ja.com

python3の_pickleは、大量のデータの保存には機能しません

データをディスクに保存するために_pickleを適用しようとしています。しかし、_pickle.dumpを呼び出すと、エラーが発生しました

OverflowError: cannot serialize a bytes object larger than 4 GiB

これは_pickleを使用するのに厳しい制限ですか? (python2の場合はcPickle

31
Jake0x32

もはやPython 3.4にはPEP 3154とPickle 4.0があります
https://www.python.org/dev/peps/pep-3154/

ただし、プロトコルのバージョン4を使用する必要があると言う必要があります。
https://docs.python.org/3/library/pickle.html

pickle.dump(d, open("file", 'w'), protocol=4)
61
Eric Levieil

はい、これはハードコーディングされた制限です。 from save_bytes function

else if (size <= 0xffffffffL) {
    // ...
}
else {
    PyErr_SetString(PyExc_OverflowError,
                    "cannot serialize a bytes object larger than 4 GiB");
    return -1;          /* string too large */
}

プロトコルは4バイトを使用してオブジェクトのサイズをディスクに書き込みます。つまり、最大2のサイズしか追跡できません。32 == 4GB。

bytesオブジェクトを、それぞれが4GB未満の複数のオブジェクトに分割できる場合でも、もちろんデータをピクルスに保存できます。

4
Martijn Pieters

Pickleが機能しない理由については、上記のすばらしい回答があります。しかし、まだPython 2.7で動作しません。これは、まだPython 2.7であり、特にNumPyをサポートしたい場合に問題になります(4G上のNumPyアレイは失敗します)。

OCシリアル化を使用できます。これは、4Gigを介したデータで機能するように更新されています。 Python C拡張モジュールが利用可能です:

http://www.picklingtools.com/Downloads

ドキュメントを見てください:

http://www.picklingtools.com/html/faq.html#python-c-extension-modules-new-as-of-picklingtools-1-6-0-and-1-3-

しかし、ここに簡単な要約があります:picdumpのダンプとロードによく似たocdumpsとocloadsがあります::

from pyocser import ocdumps, ocloads
ser = ocdumps(pyobject)   : Serialize pyobject into string ser
pyobject = ocloads(ser)   : Deserialize from string ser into pyobject

OCシリアル化は1.5〜2倍高速で、C++でも動作します(言語を混合している場合)。すべての組み込み型で機能しますが、クラスでは機能しません(一部言語間であり、PythonからC++クラスを構築するのが難しいためです)。

1
rts1