Я использовал Element Tree в python для анализа моего xml-файла размером 66 GB
для создания инвертированного индекса. Файл представляет собой XML-файл Википедии, который содержит около 17000000
документов в тегах <page>
.
Из того, что я мог собрать в сети, связанной с анализом такого большого количества данных, я познакомился с использованием elem.clear()
, который освобождает память, выделяемую каждому тегу после его использования. После прочтения каждого 8000
документов я записываю его в файл, стираю память, занятую для переменных, работающих с данными этих 8000
файлов, и затем снова запускаю.
До сих пор мне удавалось без проблем проанализировать 15GB
файла, но теперь мой ноутбук замедлился до почти замороженного состояния. Может кто-нибудь сказать мне, где утечка памяти?
Функции, которые я написал для создания и записи инвертированного индекса, не имеют никаких ссылочных циклов. Таким образом, я предполагаю, что как только я вернусь из этих функций, все переменные будут освобождены автоматически. Кроме того, я не использую какие-либо глобальные списки или словари, размер которых постоянно увеличивается внутри любой из этих функций. Все файловые указатели закрываются после того, как запись для этого чанка завершена.
def parseXML(xmlfile):
newsitems = []
tempcnt=1
pageSize=8000
stop_words = set(stopwords.words('english'))
nsmap={}
totalWords=0
invertedIndexNo=1
news={}
for event, elem in ET.iterparse(xmlfile, events=('start','end','start-ns','end-ns')):
if event=='start-ns':
ns,url=elem
nsmap[ns]=url
if event=='end':
if elem.tag==fixtag('','id',nsmap) and elem.text is not None:
if news.get('i')==None:
news['i']=elem.text.encode('utf-8')
elif elem.tag==fixtag('','title',nsmap) and elem.text is not None:
news['t']=elem.text.encode('utf-8')
elif elem.tag==fixtag('','text',nsmap) and elem.text is not None:
news['b'], news['r'], news['g']=giveBodyRefCateg(elem.text)
elif elem.tag==fixtag('','page',nsmap) and len(news)>0:
newsitems.append(news)
tempcnt+=1
news={}
elem.clear()
# if getsizeof(newsitems)>0.1*1000*1000:
if tempcnt>pageSize:
invertedIndex=refine(newsitems,stop_words)
writeBlockInvertedIndex(invertedIndex,invertedIndexNo)
print(\"The size:\",getsizeof(newsitems),getsizeof(invertedIndex))
invertedIndexNo+=1
tempcnt=1
totalWords+=len(invertedIndex)
del newsitems[:]
del invertedIndex
gc.collect()
invertedIndex=refine(newsitems,stop_words)
writeBlockInvertedIndex(invertedIndex,invertedIndexNo)
totalWords+=len(invertedIndex)
del newsitems[:]
return invertedIndexNo,totalWords