2010-06-15 10 views
7

क्या किसी को पाइथन में बहुत बड़ी एक्सएमएल फाइलें (उदाहरण के लिए 100-500 एमआईबी) उत्पन्न करने के लिए मेमोरी कुशल तरीके से पता है?पायथन में बहुत बड़ी एक्सएमएल फाइलें उत्पन्न करना?

मैं lxml का उपयोग कर रहा हूं, लेकिन स्मृति उपयोग छत के माध्यम से है।

+1

क्या यह एक अच्छा विचार है? * ऐसी फाइल * उपभोग करने जा रहा है? –

+1

500 एमआईबी एक्सएमएल फ़ाइल? हां - अगर मेरी एक्सएमएल फाइलें 500 एमआईबीबी तक पहुंच गईं तो मैं एक और अधिक कुशल फ़ाइल प्रारूप पर विचार करूंगा! :-) –

+0

पसंद से नहीं, मेरा विश्वास करो :) –

उत्तर

6

शायद आप खुद को एक्सएमएल बनाने/बनाने के बजाय एक टेम्पलेटिंग इंजन का उपयोग कर सकते हैं?

Genshi उदाहरण के लिए xml- आधारित है और स्ट्रीमिंग आउटपुट का समर्थन करता है। एक बहुत ही बुनियादी उदाहरण:

from genshi.template import MarkupTemplate 

tpl_xml = ''' 
<doc xmlns:py="http://genshi.edgewall.org/"> 
<p py:for="i in data">${i}</p> 
</doc> 
''' 

tpl = MarkupTemplate(tpl_xml) 
stream = tpl.generate(data=xrange(10000000)) 

with open('output.xml', 'w') as f: 
    stream.render(out=f) 

इसमें कुछ समय लग सकता है, लेकिन स्मृति उपयोग कम रहता है।

Mako templating इंजन (नहीं "मूल रूप से" xml) के लिए एक ही उदाहरण है, लेकिन बहुत तेजी से:

from mako.template import Template 
from mako.runtime import Context 

tpl_xml = ''' 
<doc> 
% for i in data: 
<p>${i}</p> 
% endfor 
</doc> 
''' 

tpl = Template(tpl_xml) 

with open('output.xml', 'w') as f: 
    ctx = Context(f, data=xrange(10000000)) 
    tpl.render_context(ctx) 

पिछले उदाहरण, के बारे में 20 सेकंड के लिए अपने लैपटॉप पर भाग गया एक (वैसे बहुत ही सरल उत्पादन) 151 एमबी एक्सएमएल फ़ाइल, बिल्कुल कोई स्मृति समस्या नहीं है।(विंडोज़ टास्क मैनेजर के अनुसार यह लगभग 10 एमबी पर स्थिर रहा)

आपकी ज़रूरतों के आधार पर, यह एसएक्स आदि का उपयोग करने से एक्सएमएल उत्पन्न करने का एक मित्रवत और तेज़ तरीका हो सकता है ... यह देखने के लिए दस्तावेज़ देखें कि आप क्या कर सकते हैं इन इंजनों के साथ (अन्य भी हैं, मैंने अभी इन दोनों को उदाहरण के रूप में चुना है)

+1

शानदार विचार! यह निश्चित रूप से विचार करने लायक है। –

2

इतनी बड़ी एक्सएमएल फ़ाइल उत्पन्न करने का एकमात्र तरीका तरीका लाइन से लाइन है, जिसका मतलब है कि राज्य मशीन चलाने के दौरान प्रिंटिंग, और परीक्षण के

+0

उत्तर के लिए धन्यवाद। SAX ftl .. argh ... –

2

जाहिर है, आपको स्मृति में पूरे पेड़ (चाहे डोम या एट्री या जो भी हो) बनाने से बचना होगा। लेकिन सबसे अच्छा तरीका आपके डेटा के स्रोत पर निर्भर करता है और आपके आउटपुट की संरचना कितनी जटिल और अंतःस्थापित होती है।

यदि यह बड़ा है क्योंकि इसे काफी स्वतंत्र वस्तुओं के हजारों उदाहरण मिलते हैं, तो आप बाहरी आवरण उत्पन्न कर सकते हैं, और फिर प्रत्येक आइटम के लिए पेड़ बना सकते हैं और फिर आउटपुट में प्रत्येक टुकड़े को क्रमबद्ध कर सकते हैं।

यदि टुकड़े इतने स्वतंत्र नहीं हैं, तो आपको कुछ अतिरिक्त बहीखाता करने की आवश्यकता होगी - जैसे कि उत्पन्न आईडी & idrefs का डेटाबेस प्रबंधित करें।

मैं इसे 2 या 3 भागों में तोड़ दूंगा: एक सैक्स इवेंट प्रोड्यूसर, एक आउटपुट सीरियलाइज़र सैक्स घटनाएं खाने और वैकल्पिक रूप से, अगर वस्तुओं या पेड़ों के रूप में कुछ स्वतंत्र टुकड़ों के साथ काम करना आसान लगता है, तो उन वस्तुओं को बनाने के लिए कुछ और फिर serializer के लिए उन्हें sax घटनाओं में बदल दें।

शायद आप सैक्स घटनाओं से निपटने के बजाय इसे सीधे टेक्स्ट आउटपुट के रूप में प्रबंधित कर सकते हैं: यह इस बात पर निर्भर करता है कि यह कितना जटिल है।

यह स्मृति में बड़ी संरचनाओं के निर्माण के बिना आउटपुट स्ट्रीमिंग के तरीके के रूप में पाइथन जेनरेटर का उपयोग करने के लिए भी एक अच्छी जगह हो सकती है।

+0

हम्म, हाँ इसमें काफी स्वतंत्र वस्तुओं के हजारों उदाहरण होंगे। मुझे लगता है कि मैं उस दृष्टिकोण को कर सकता हूं। धन्यवाद। –

+0

ऊपर सुझाए गए टेम्पलेटिंग दृष्टिकोण शायद आसान है - खासकर यदि अलग ऑब्जेक्ट/भाग संभालने के लिए पर्याप्त छोटे हैं। पैक्सन जनरेटर का उपयोग कर सह-रूटीन के रूप में SAX निर्माता/उपभोक्ता जोड़ी को चलाने का विकल्प वैकल्पिक होगा यदि चीजें आसानी से छोटे हिस्सों में आसानी से नहीं टूट जातीं। –

0

यदि आपका दस्तावेज़ बहुत नियमित है (जैसे डेटाबेस रिकॉर्ड का समूह, सभी एक ही प्रारूप में) तो आप अपनी "xe" लाइब्रेरी का उपयोग कर सकते हैं।

http://home.avvanta.com/~steveha/xe.html

XE पुस्तकालय सिंडिकेशन फ़ीड पैदा (एटम, आरएसएस, आदि) के लिए डिजाइन किया गया था और मुझे लगता है कि इसका इस्तेमाल करने के लिए आसान है। मुझे इसे Python 2.6 के लिए अपडेट करने की आवश्यकता है, और मैंने अभी तक इसके बारे में खेद नहीं किया है।

+0

बहुत अच्छा। क्या यह अधिक स्मृति स्मृति है lxml का उपयोग करने से? –

+0

सुनिश्चित नहीं है। मैंने अभी तक एलएक्सएमएल नहीं देखा है। यदि आप एक ही समय में अपना पूरा डेटा धारण कर रहे हैं, तो आप कम से कम 500 एमआईबी धारण कर रहे हैं इससे कोई फर्क नहीं पड़ता। लेकिन अगर आप लूप में सामान लिख रहे हैं, तो आप उसी एक्सई डेटा स्ट्रक्चर का पुनः उपयोग कर सकते हैं, जो स्मृति को बचाएगा। लेकिन शायद आप एलएक्सएमएल के साथ एक ही काम कर सकते हैं? – steveha