【问题标题】:xml.etree.ElementTree iterparse() still using lots of memory?xml.etree.ElementTree iterparse() 仍然使用大量内存?
【发布时间】:2014-08-05 05:51:30
【问题描述】:

我一直在尝试使用 iterparse 来减少需要处理大型 XML 文档的脚本的内存占用。这是一个例子。我编写了这个简单的脚本来读取 TMX 文件并将其拆分为一个或多个输出文件,以不超过用户指定的大小。尽管使用了 iterparse,但当我将 886MB 文件拆分为 100MB 文件时,脚本会耗尽所有可用内存(在使用 8MB 中的 6.5 块的情况下爬行)。

我做错了吗?为什么内存使用率这么高?

#! /usr/bin/python
# -*- coding: utf-8 -*-
import argparse
import codecs
from xml.etree.ElementTree import iterparse, tostring
from sys import getsizeof

def startNewOutfile(infile, i, root, header):
    out = open(infile.replace('tmx', str(i) + '.tmx'), 'w')
    print >>out, '<?xml version="1.0" encoding="UTF-8"?>'
    print >>out, '<!DOCTYPE tmx SYSTEM "tmx14.dtd">'
    print >>out, roottxt
    print >>out, headertxt
    print >>out, '<body>'
    return out

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-m', '--maxsize', dest='maxsize', required=True, type=float, help='max size (in MB) of output files')
    parser.add_argument(dest='infile', help='.tmx file to be split')
    args = parser.parse_args()

    maxsize = args.maxsize * 1024 * 1024

    nodes = iter(iterparse(args.infile, events=['start','end']))

    _, root = next(nodes)
    _, header = next(nodes)

    roottxt = tostring(root).strip()
    headertxt = tostring(header).strip()

    i = 1
    curr_size = getsizeof(roottxt) + getsizeof(headertxt)
    out = startNewOutfile(args.infile, i, roottxt, headertxt)

    for event, node in nodes:
        if event =='end' and node.tag == 'tu':
            nodetxt = tostring(node, encoding='utf-8').strip()
            curr_size += getsizeof(nodetxt)
            print >>out, nodetxt
        if curr_size > maxsize:
            curr_size = getsizeof(roottxt) + getsizeof(headertxt)
            print >>out, '</body>'
            print >>out, '</tmx>'
            out.close()
            i += 1
            out = startNewOutfile(args.infile, i, roottxt, headertxt)
        root.clear()

    print >>out, '</body>'
    print >>out, '</tmx>'
    out.close()

【问题讨论】:

    标签: python xml elementtree iterparse


    【解决方案1】:

    在相关问题中找到答案:Why is elementtree.ElementTree.iterparse using so much memory?

    在 for 循环的每次迭代中,不仅需要 root.clear(),还需要 node.clear()。因为我们同时处理开始和结束事件,所以我们需要注意不要过早删除 tu 节点:

    for e, node in nodes:
        if e == 'end' and node.tag == 'tu':
            nodetxt = tostring(node, encoding='utf-8').strip()
            curr_size += getsizeof(nodetxt)
            print >>out, nodetxt
            node.clear()
        if curr_size > maxsize:
            curr_size = getsizeof(roottxt) + getsizeof(headertxt)
            print >>out, '</body>'
            print >>out, '</tmx>'
            out.close()
            i += 1
            out = startNewOutfile(args.infile, i, roottxt, headertxt)
        root.clear()
    

    【讨论】:

      猜你喜欢
      • 2014-12-13
      • 1970-01-01
      • 2013-06-15
      • 2021-07-09
      • 2017-11-16
      • 1970-01-01
      • 2010-11-12
      相关资源
      最近更新 更多