lxml iterparse标记参数和内存消耗

时间:2014-02-04 10:09:51

标签: python xml memory iterparse

我正在使用lxml.iterparse处理大型xml文件。这很好用,但随着我的文件最近变得更大,我发现iterparse行为填补了我的记忆。请考虑以下代码,该代码编写一个包含300000个元素的文件和300000个elem元素以及300000个other_elem元素:

els = ('<elem><subel1>{0}</subel1><subel2>{0}</subel2><subel3>{0}</subel3><subel4>{0}</subel4><subel5>{0}</subel5><subel6>{0}</subel6></elem>'.format(x) for x in range(300000))
other_els = ('<other_elem><subel1>{0}</subel1><subel2>{0}</subel2><subel3>{0}</subel3><subel4>{0}</subel4><subel5>{0}</subel5><subel6>{0}</subel6></other_elem>'.format(x) for x in range(300000))

with open('/tmp/test.xml', 'w') as fp:
   fp.write('<root>\n')
   fp.write('<elements>\n')
   for el in els:
       fp.write(el+'\n')
   fp.write('</elements>\n')
   fp.write('<other_elements>\n')
   for el in other_els:
       fp.write(el+'\n')
   fp.write('</other_elements>\n')
   fp.write('</root>\n')

然后,我使用以下内容仅解析elem(并不对它们执行任何操作),同时不时打印内存使用情况:

from lxml import etree
import psutil
import os

process = psutil.Process(os.getpid())
gen = etree.iterparse('/tmp/test.xml', tag='elem')
elscount = 0
for ac,el in gen:
    elscount += 1
    el.clear()
    if el.getprevious() is not None:
        del(el.getparent()[0])
    if elscount % 10000 == 0:
        print process.get_memory_info().rss/(1024*1024)

print process.get_memory_info().rss/(1024*1024)

输出显示内存使用率低,直到结束时突然跳转。当我尝试读取不包含other_elem的文件时,此行为消失。一个较慢的解决方法是将tag参数遗漏给iterparse,而是使用if结构进行测试,使内存空闲,可能是因为它可以对不匹配的元素执行el.clear()。因此,我的问题不是如何解决这个问题,而是为什么在它不必输出的元素上浪费内存,或者可能,我在这里做错了什么呢?

0 个答案:

没有答案