hereの提案に従って、次のコードで作成された ZODB を使用してデータを保存しました。
# structure of the data [around 3.5 GB on disk]
bTree_container = {key1:[ [2,.44,0], [1,.23,0], [4,.21,0] ...[10,000th element] ], key2:[ [3,.77,0], [1,.22,0], [6,.98,0] ..[10,000th element] ] ..10,000th key:[[5,.66,0], [2,.32,0], [8,.66,0] ..[10,000th element]]}
# Code used to build the above mentioned data set
for Gnodes in G.nodes(): # Gnodes iterates over 10000 values
Gvalue = someoperation(Gnodes)
for i,Hnodes in enumerate(H.nodes()): # Hnodes iterates over 10000 values
Hvalue =someoperation(Hnodes)
score = SomeOperation on (Gvalue,Hvalue)
btree_container.setdefault(Gnodes, PersistentList()).append([Hnodes, score, 0]) # build a list corresponding to every value of Gnode (key)
if i%5000 == 0 # save the data temporarily to disk.
transaction.savepoint(True)
transaction.commit() # Flush all the data to disk
今、私は(別のモジュールで)(1)保存されたデータを変更し、(2)それを並べ替えたいと思っています。以下は私が使用していたコードです:
storage = FileStorage('Data.fs')
db = DB(storage)
connection = db.open()
root = connection.root()
sim_sorted = root[0]
# substitute the last element in every list of every key (indicated by 0 above) by 1
# This code exhausts all the memory, never get to the 2nd part i.e. the sorting
for x in sim_sorted.iterkeys():
for i,y in enumerate(sim_sorted[x]):
y[3] = 1
if i%5000 ==0
transaction.savepoint()
# Sort all the lists associated with every key in he reverse order using middle element as key
[sim_sorted[keys].sort(key = lambda x:(-x[1])) for keys in sim_sorted.iterkeys()]
ただし、値を編集するために使用されるコードは、すべてのメモリを使い果たしています (決して並べ替えを行うことはありません)。これがどのように機能するかはわかりませんが、コードに何かひどく問題があり、ZODB がすべてをメモリに取り込んでいるため、問題が発生しているように感じます。メモリの問題に遭遇することなく、ZODB に格納された要素の置換と並べ替えなど、望ましい効果を達成するための正しい方法は何でしょうか? また、コードは非常に遅いです。それを速くするための提案はありますか?
[注: これらの変更をデータベースに書き戻す必要はありません]
connection.cacheMinimize()
編集内部ループの後にコマンドを追加することでメモリ使用量が少し改善されたようですが、しばらくすると RAM 全体が消費され、困惑しています。