所以我一直在使用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更快地完成。
答案 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用于泡沫解组。