Python2 sax解析器,大文件的最佳速度和性能?

时间:2014-03-04 11:48:33

标签: xml sax python-2.x suds

所以我一直在使用suds,这对于使用web服务非常有益。

遇到性能问题,对于某些数据来说cpu会很难达到,完成请求需要60多秒才能完成,这需要gunicorn,suds到webservice等等。

使用line_profiler,objgraph,memory_profiler等查看它,我发现罪魁祸首是解析一个9.2mb xml文件需要13秒,这是来自web服务的响应。

那可不正常吗?只有9.2mb,我看到99%的时间用于解析它,解析是通过“from xml.sax import make_parser”完成的,这意味着标准的python?

任何更快的xml解析器都有大文件吗?

我会仔细研究XML中究竟是什么类型的结构,但到目前为止我知道它的“UmResponse”包含大约7000个“Document”元素,每个元素包含10-20行元素。

编辑:进一步调查我看到那些13中的一半花在suds / sax / ...中的肥皂泡沫当然可能是泡沫问题,而不是python库。

EDIT2:suds unmarshaller使用大部分时间处理这个,大约50s,使用sax解析也很慢,使用xml.minidom的pysimplesoap需要大约13s和大量内存。然而lxml.etree低于2s且objectify也非常快,足够快以使用它而不是ElementTree(这个特定xml比cElementTree更快,0.5s用于其他的0.17s)

解决方案:Suds允许参数retxml为true,在没有解析和解组的情况下返回XML,从那里我可以用lxml更快地完成。

1 个答案:

答案 0 :(得分:4)

使用sax解析sax需要时间,甚至更多的suds src绑定/绑定中的unmarhsalling方法使用类umx / Typed非常多。

解决方案,绕过所有这些: 将retxml = True传递给客户端,这样suds就不会解析和解组,这是suds的绝佳选择!而是使用lxml,我发现它是最快的,不知何故甚至比cElementTree更快。

from lxml import objectify
from lxml.etree import XMLParser

现在另一个问题是xml有一个巨大的txt节点,超过10mb,所以lxml会保释,XMLParser需要标志huge_tree = True来吞下并处理大数据文件。设置它是这样的,set_element_class_lookup真的有很大的好处,没有它你真的没有得到ObjectifedElement。

parser = XMLParser(remove_blank_text=True, huge_tree=True)
parser.set_element_class_lookup(objectify.ObjectifyElementClassLookup())
objectify.set_default_parser(parser)
obj = objectify.fromstring(ret_xml)
# iter here and return Body or Body[0] or whatever you need
#so all code which worked with suds unmarshaller works with objectified aswell 

然后剩余的代码在suds进行解组时按属性查找元素它工作正常(只需在返回soap信封的Body之后),不需要麻烦xpath或iteraparse xml元素。

objectify在1-2s内完成工作,相比50-60s用于泡沫解组。