2012-07-04 4 views
3

После предложений, приведенных here я хранятся мои данные с помощью ZODB, созданных с помощью следующего фрагмента кода:изменяющие данные в 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 без проблем с памятью? Также код очень медленный, предложение ускорить его?

[Примечание: Это не нужно для меня, чтобы написать эти изменения обратно в базу данных]

EDIT Там, кажется, небольшое улучшение в использовании памяти, добавив команду connection.cacheMinimize() после внутреннего цикла, однако еще раз после того, как Некоторое время все ОЗУ потребляется, что оставляет меня озадаченным.

ответ

1

Вы уверены, что это не сортировка, которая убивает вашу память?

Обратите внимание, что я ожидаю, что каждый PersistentList должен вписаться в память; это одна постоянная запись, поэтому она будет загружаться в целом при доступе.

Я бы изменить код, чтобы работать, как это и посмотреть, что происходит:

for x in sim_sorted.iterkeys(): 
    for y in sim_sorted[x]: 
     y[3] = 1 
    sim_sorted[x].sort(key=lambda y: -y[1]) 
    transaction.savepoint() 

Теперь вы обрабатываете весь список в один присест и сортировать его; в конце концов, он уже загружен в память в одном. После обработки вы сообщаете ZODB, что вы сделали на этом этапе, и весь измененный список будет удален на временное хранение. Там мало смысла смывать его, когда делается только на полпути.

Если вы все еще не вписываетесь в память, вам нужно переосмыслить структуру данных и разделить большие списки на более мелкие постоянные записи, чтобы вы могли работать над кусками за один раз без загрузки целого вещь в одном.

+0

Martjin: Это действительно странно! Хотя, я уверен, что это не сортировка, так как я поставил контрольную точку в свой код, и она никогда не доходила до раздела сортировки, но почему-то парадигма, которую вы рекомендовали, кажется, работает! Вы бы рекомендовали использовать метод connection.cacheMinimize()? –

+0

Martjin: Я уверен, что один список достаточно мал, чтобы вписаться в память (в конце концов я строю его таким образом). Хотя выше это работает до некоторой степени, но все же большая часть моей RAM медленно преобразуется в * неактивную память *. Я не уверен, как это сделать. Любые комментарии ? –

+0

Прежде всего: не уверен, что 'cacheMinimize' будет делать многое; он очистит любые объекты, которые не были изменены. Но так как вы только загружаете объекты, которые вы * делаете * меняете, я думаю, что это не будет иметь больших шансов. Во-вторых: не беспокойтесь о неактивной памяти; ваша ОС вернет это, когда потребуется. Это стратегия, в которой процессы сохраняют память, даже если они в настоящее время ее не используют, основываясь на том, что они вскоре будут повторно использовать ее. –

Смежные вопросы