打最大限の再帰に深みのある漬け/cPickle
質問
その背景:私の構築trieを表す辞書を使用し、最小限の構築アルゴリズムです。の入力一覧表は4.3M utf-8文字列、並び辞書的.このグラフは非環式で、最大深度の638ノード。最初の行のスクリプトの再帰制限1100介 sys.setrecursionlimit()
.
の問題:持ってき方など、さすがだなと私がserialize私のtrieをディスクだったので、読み込みメモリな初から再取得(約22分)しかし、両 pickle.dump()
や cPickle.dump()
, 両方のテキストおよびバイナリプロトコル各時間を取得しますスタックトレースとは、以下に示すようになります:
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 663, in _batch_setitems
save(v)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 725, in save_inst
save(stuff)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pickle.py", line 648, in save_dict
self.memoize(obj)
RuntimeError: maximum recursion depth exceeded
私のデータ構造は比較的シンプルです: trie
への参照が含まれて始め、義されています。 dfa_state
含まれるbooleanフィールドは、文字列の分野では、辞書のマッピングからラベルの状態です。
私はあまり馴染みの仕組み pickle
-は私の最大再帰深度が必要なよ/equal n倍の深さは、trieの一n?またはこのようん知らなか?
更新: 設定の再帰深度3000ん、このavenueんが期待できます。
更新2: だった右;また近視眼と漬物をご利用い小さな入れ子の深さによりデフォルトの再帰限界がある。10,000かったですよね。
他のヒント
ピクルスは、再帰的にあなたのトライを歩くする必要がありません。ピクルスは、仕事をするために、関数呼び出しのちょうど5つのレベルを使用している場合は深さ638のあなたのトライは3000以上にレベルセットが必要になります。
がはるかに大きい数を試してみて、再帰制限は再帰が無限の穴に落ちる場合が長すぎる待つことからプロテクトのユーザーにただそこに実際にある。
ピクルスハンドルサイクル[OK]を、ので、それはあなたのトライがある
でサイクルを持っていても問題ではありませんスタックサイズのものとともに増加し resource.setrlimit
防segfault
ご利用の場合だけで sys.setrecursionlimit
, することができsegfaultに到達した場合、最大スタックサイズによって許可されるLinuxカーネルです。
この値を増すことができると resource.setrlimit
としてお話ししたように、これまで: 設定が大きく、pythonスクリプト
import pickle
import resource
import sys
print resource.getrlimit(resource.RLIMIT_STACK)
print sys.getrecursionlimit()
max_rec = 0x100000
# May segfault without this line. 0x100 is a guess at the size of each stack frame.
resource.setrlimit(resource.RLIMIT_STACK, [0x100 * max_rec, resource.RLIM_INFINITY])
sys.setrecursionlimit(max_rec)
a = []
# 0x10 is to account for subfunctions called inside `pickle`.
for i in xrange(max_rec / 0x10):
a = [a]
print pickle.dumps(a, -1)
参照: が必要な場合は、当社まで再帰深度ドするにはどうしたらいいのか、ですか?
デフォルトの最大値というのは8Mb.
試Ubuntu16.10、Python2.7.12.
あなたの構造は確かに非環式であることをダブルチェックます。
あなたも、さらに制限をぶつけてみてください。そこプラットフォーム依存のハード最大のだが、50000をしようとすることは合理的である。
また、あなたのトライの些細な小さなバージョンを酸洗してみてください。ピクルスは、それが唯一のカップル3文字の単語を格納していますにもかかわらず死亡した場合、あなたはあなたのトライといくつかの根本的な問題があると知って、酸洗いません。あなたは10Kの単語を格納しようとすると、それだけで発生した場合でも、それはピクルスで、プラットフォームの制限の故障かもしれません。
私のニーズはややすぐに出ました。唯一のことは、あなたがあなたのファイルをロードする際、再びあなたが辞書に戻ってそれを変換しなければならないということです。
import json
# Saving the dictionary
with open('filename.txt', 'w') as file_handle:
file_handle.write(str(dictionary))
# Importing the .txt file
with open('filename.txt', 'r') as file_handle:
f = '"' + file_handle.read() + '"'
# From .txt file to dictionary
dictionary = eval(json.loads(f))
これはあなたがJSON形式を使用して辞書をエクスポートしようとして動作しない場合ます。