2014-03-04 19 views
3

所以我一直在使用泡沫很有益的消費Web服務。Python2薩克斯分析器,大型文件的最佳速度和性能?

遇到一個性能問題,對於某些數據cpu會難以達到的情況,需要60多秒才能完成請求,該請求由gunicorn服務,發佈到webservice等等。

用line_profiler,objgraph,memory_profiler等來查看它,我發現罪魁禍首是需要13s來解析一個9.2MB的xml文件,這是來自web服務的響應。

這不能正常嗎?只有9.2mb,我發現有99%的時間花在解析它,解析是通過「from xml.sax import make_parser」來完成的,這意味着標準的python?

任何更快的XML解析器在那裏的大文件?

虐待看看到底是什麼樣的結構是在XML,但到目前爲止,我知道它的「UmResponse」,其中包含7000左右「一號文件」的元素,每個包含10-20線元素。

編輯:進一步調查我看到一半的13s是在suds/sax/...中的泡沫處理程序中度過的...... hm當然可以是suds問題而不是python庫。

EDIT2:suds unmarshaller用了大部分時間處理這個,大約50s,用sax解析也很慢,使用xml.minidom的pysimplesoap需要大約13s和大量的內存。然而,lxml.etree低於2s,物化也非常快速,足夠快以使用它來代替ElementTree(這比這個特定xml的cElementTree更快,0.5s對於其他0.17s)

解決方案:Suds允許參數retxml爲真,在不解析和解組的情況下返回XML,從那裏我可以用lxml更快地完成。

+0

您可以嘗試使用Python libxml2綁定或lxml。這可能會稍微快一點,但我認爲這不會產生巨大的影響。你已經聲明它完成*** 60秒***來完成請求,並且只花費了13秒***來分析文件。假設通過一些奇蹟你可以加速解析需要0秒,你仍然看着*** 50秒***來解析文件。 – CadentOrange

+0

@CadentOrange多數民衆贊成真實,進一步看,13s是解析使用sax解析器,或minidom解析器他們是大約相同的速度,但然後泡沫unmarshaller方法使用了50年代。啊。所以suds需要花費很多時間,因爲sax解析器和它的ContentHandler,然後構建某種類型的泡沫DOM比minidom需要更多的時間。最快的是ElementTree並物化。 – rapadura

+0

這是一個非常好的發現。我使用泡沫,我應該如此(不幸)需要解析一個大的XML響應,你的文章是有幫助的。 – CadentOrange

回答

3

使用sax進行解析需要時間,甚至更多使用類umx/Typed的suds src bindings/binding中的unmarhsalling方法。

解決方案,繞過所有這些: Pass retxml =真的客戶端,使泡沫不解析和解組,真棒泡沫選項!取而代之的是使用lxml,我發現它是最快的,比cElementTree快得多。

from lxml import objectify 
from lxml.etree import XMLParser 

現在另一個問題是,XML有聯接的巨大TXT,超過10MB,所以LXML會救助的XMLParser的需要標誌huge_tree =真吞和處理大型數據文件。像這樣設置,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 

然後由物業擡頭元素時,泡沫已解組工作的罰款(只是返回SOAP信封的身體後)的代碼的其餘部分,無需使用XPath或iteraparse XML元素麻煩。

objectify是否在1-2s工作,相比之下50-60s是泡沫解組。