2009-10-01 9 views
60

का उपयोग करने का निर्णय लेने पर निर्णय लेना मैं एक कस्टम ऑब्जेक्ट -> एक्सएमएल क्रमबद्धता उपयोगिता को अनुकूलित कर रहा हूं, और यह सब कुछ किया और काम कर रहा है और यह मुद्दा नहीं है।XmlDocument बनाम XmlReader

यह फ़ाइल को XmlDocument ऑब्जेक्ट में लोड करके काम करता है, फिर सभी बच्चे नोड्स के माध्यम से फिर से चल रहा है।

मुझे लगा कि शायद का उपयोग XmlDocument होने की बजाय पूरी चीज़ को लोड/पार्स करना तेज होगा, इसलिए मैंने उस संस्करण को भी लागू किया।

एल्गोरिदम बिल्कुल वही हैं, मैं XmlNode बनाम XmlReader से निपटने की कार्यक्षमता को सारणी देने के लिए एक रैपर वर्ग का उपयोग करता हूं। उदाहरण के लिए, GetChildren विधियों का उत्पादन या तो बच्चे XmlNode या एक उपट्री XmlReader देता है।

इसलिए मैंने दोनों संस्करणों का परीक्षण करने और एक गैर-तुच्छ डेटा सेट (लगभग 1,350 तत्वों के साथ एक 900 केबी एक्सएमएल फ़ाइल) का उपयोग करने के लिए एक परीक्षण चालक लिखा।

हालांकि, JetBrains dotTRACE का उपयोग करके, मुझे लगता है कि XmlReader संस्करण वास्तव में XmlDocument संस्करण से धीमा है! ऐसा लगता है कि XmlReader में कुछ महत्वपूर्ण प्रसंस्करण शामिल हैं जब मैं बाल नोड्स पर पुनरावृत्ति कर रहा हूं।

तो मैं कहता हूँ कि सभी इस पूछने के लिए:

क्या XmlDocument और XmlReader, और किस परिस्थिति में के फायदे/नुकसान या तो आप का उपयोग करना चाहिए रहे हैं?

मेरा अनुमान है कि फ़ाइल आकार सीमा है जिस पर XmlReader प्रदर्शन में अधिक किफायती हो जाता है, साथ ही कम स्मृति-गहन भी हो जाता है। हालांकि, यह सीमा 1 एमबी से ऊपर प्रतीत होती है।

मैं ReadSubTree हर बार बच्चे नोड्स पर कार्रवाई करने के फोन कर रहा हूँ:

public override IEnumerable<IXmlSourceProvider> GetChildren() 
{ 
    XmlReader xr = myXmlSource.ReadSubtree(); 
    // skip past the current element 
    xr.Read(); 

    while (xr.Read()) 
    { 
     if (xr.NodeType != XmlNodeType.Element) continue; 
     yield return new XmlReaderXmlSourceProvider (xr); 
    } 
} 

कि परीक्षण एकल स्तर (यानी विस्तृत & उथले) पर वस्तुओं का एक बहुत कुछ करने के लिए लागू होता है - लेकिन मुझे आश्चर्य है कि कैसे अच्छी तरह से XmlReader किरायों जब एक्सएमएल गहराई & चौड़ा है? अर्थात। जिस एक्सएमएल के साथ मैं काम कर रहा हूं वह डेटा ऑब्जेक्ट मॉडल, 1 ऑब्जेक्ट ऑब्जेक्ट की तरह कई बच्चे ऑब्जेक्ट्स आदि है: 1..M..M..M

मैं पहले से ही एक्सएमएल की संरचना को नहीं जानता हूं, मैं पार्सिंग कर रहा हूं, इसलिए मैं कर सकता हूं इसके लिए अनुकूलित नहीं है।

+1

मैंने हमेशा सोचा है कि XmlDocument और XmlReader दोनों क्यों थे ... –

+0

वास्तव में XMLDocument और XMLReader के लिए एक और विकल्प है। अब आप LINQ का उपयोग XML से कर सकते हैं लेकिन वास्तव में XMLReader अधिकतर तरीकों से अधिक कुशल है। – Tarik

+2

रुको। आपकी 'GetChildren' विधि' XmlReader' लौटाती है? आपका मतलब है, आप हर बार जब आप एक बच्चे नोड को संसाधित करते हैं तो आप 'XmlReader.Create() 'को कॉल कर रहे हैं? –

उत्तर

63

मैं आम तौर पर नहीं एक सबसे तेजी से परिप्रेक्ष्य से, बल्कि एक मेमोरी उपयोग नजरिए से इसे देखा है। सभी कार्यान्वयन उन परिदृश्य परिदृश्यों के लिए पर्याप्त तेज़ रहे हैं जिनका मैंने उपयोग किया है (विशिष्ट उद्यम एकीकरण)।

हालांकि, जहां मैं गिर गया हूं, और कभी-कभी शानदार रूप से, एक्सएमएल के सामान्य आकार को ध्यान में रखकर मैं काम नहीं कर रहा हूं। यदि आप इसके बारे में सोचते हैं तो आप स्वयं को कुछ दुख बचा सकते हैं।

एक्सएमएल मेमोरी में लोड होने पर ब्लोट हो जाता है, कम से कम XmlDocument या XPathDocument जैसे डीओएम रीडर के साथ। कुछ 10: 1 की तरह? सटीक मात्रा को मापना मुश्किल है, लेकिन यदि डिस्क पर 1 एमबी है तो यह स्मृति में 10 एमबी होगा, या अधिक, उदाहरण के लिए।

किसी भी पाठक है कि अपनी संपूर्णता (XmlDocument/XPathDocument) में स्मृति में पूरे दस्तावेज़ को लोड करता है बड़ी वस्तु ढेर विखंडन, जो अंततः OutOfMemoryException रों (यहां तक ​​कि उपलब्ध स्मृति) को जन्म दे सकता से ग्रस्त हो सकते एक अनुपलब्ध सेवा में जिसके परिणामस्वरूप का उपयोग कर एक प्रक्रिया/प्रक्रिया।

के बाद से वस्तुओं है कि आकार में 85K से अधिक हैं बड़ी वस्तु ढेर पर खत्म, और आप एक 10 मिल गया है: एक डोम रीडर के साथ 1 आकार विस्फोट, आप देख सकते हैं यह बहुत पहले नहीं ले करता है अपने एक्सएमएल दस्तावेज़ बड़े ऑब्जेक्ट ढेर से आवंटित किए जा रहे हैं।

XmlDocument उपयोग करना बहुत आसान है। इसकी एकमात्र असली कमी यह है कि यह पूरे एक्सएमएल दस्तावेज़ को प्रक्रिया में स्मृति में लोड करता है। इसका उपयोग करने के लिए मोहक रूप से सरल है।

XmlReader एक स्ट्रीम आधारित पाठक है, इसलिए आपकी प्रक्रिया मेमोरी उपयोग आम तौर पर चापलूसी रखेगा लेकिन इसका उपयोग करना अधिक कठिन होगा।

XPathDocument XmlDocument का एक तेज़, केवल-पढ़ने वाला संस्करण होने लगता है, लेकिन फिर भी स्मृति 'ब्लोट' से पीड़ित है।

+4

एक्सएमएल दस्तावेज़ लोड हो रहा है, हालांकि बड़ी, मेमोरी में बड़ी वस्तुएं नहीं होती हैं। हालांकि स्ट्रिंग के रूप में एक्सएमएल को पकड़ना! यह अलग-अलग ऑब्जेक्ट्स का आकार है जो जीसी की स्मृति को डीफ्रैगमेंट करने की क्षमता के संबंध में मायने रखता है, लेकिन ऑब्जेक्ट ग्राफ़ का कुल आकार जो स्मृति उपयोग के संबंध में मायने रखता है। –

+1

एफडब्ल्यूआईडब्ल्यू मैंने एक्सडोक्यूमेंट, एक्सएमएल रीडर और एक्सएमएल डॉक्यूमेंट के बीच एक बेंचमार्क किया है। समान पथ करने के लिए क्रमश: 0.004, 0.001, और 0.6 9 2 सेकंड ले गए। – micahhoover

0

एक आकार सीमा है जिस पर XmlDocument धीमा हो जाता है, और अंत में अनुपयोगी हो जाता है। लेकिन दहलीज का वास्तविक मूल्य आपके आवेदन और एक्सएमएल सामग्री पर निर्भर करेगा, इसलिए कोई कठोर और तेज़ नियम नहीं हैं।

यदि आपकी XML फ़ाइल में बड़ी सूचियां हो सकती हैं (हजारों तत्वों का कहना है), तो आपको निश्चित रूप से XmlReader का उपयोग करना चाहिए।

9

XmlDocument संपूर्ण XML दस्तावेज़ का एक स्मृति स्मृति प्रतिनिधित्व है। इसलिए यदि आपका दस्तावेज़ बड़ा है, तो यह XmlReader का उपयोग करके इसे पढ़ने के बजाय अधिक स्मृति का उपभोग करेगा।

यह माना जा रहा है कि जब आप XmlReader का उपयोग करते हैं तो आप तत्वों को एक-एक करके पढ़ते हैं और संसाधित करते हैं और फिर इसे छोड़ दें।यदि आप XmlReader का उपयोग करते हैं और स्मृति में एक और मध्यस्थ संरचना का निर्माण करते हैं तो आपको एक ही समस्या है, और आप इसके उद्देश्य को हरा रहे हैं।

"SAX versus DOM" के लिए Google को प्रोसेसिंग एक्सएमएल के दो मॉडलों के बीच अंतर के बारे में अधिक पढ़ने के लिए।

+1

कष्टप्रद बात यह है कि बिल्कुल कोई संकेत नहीं है कि (बॉलपार्क) एक दस्तावेज़ "बड़ा" बन जाता है और एक्सएमएल रीडर किसी भी बड़े आकार के लाभ का उत्पादन शुरू करता है। क्या यह 1 केबी, 1 एमबी, या इससे भी ज्यादा है? मुझे यकीन है कि जवाब "यह निर्भर करता है", लेकिन बिना किसी सुराग के हम इन मामलों को प्रयोगात्मक रूप से केस-दर-मामले आधार पर निर्धारित करने के लिए छोड़ दिए गए हैं, ऐसे मामलों को छोड़कर जहां मनमाने ढंग से बड़े डेटा को संभालने में सक्षम होना आवश्यक है (तब एक्सएमएल रीडर स्पष्ट विकल्प है)। –

0

एन्कोडिंग अंतर इसलिए है क्योंकि दो अलग-अलग माप मिश्रित किए जा रहे हैं। यूटीएफ -32 प्रति चरित्र 4 बाइट की आवश्यकता है, और एक बाइट डेटा से स्वाभाविक रूप से धीमी है।

यदि आप बड़े (100 के) तत्व परीक्षण को देखते हैं, तो आप देखते हैं कि लोडिंग विधि के बावजूद प्रत्येक मामले के लिए लगभग 70 एमएस तक समय बढ़ता है।

यह एक (लगभग) निरंतर अंतर विशेष रूप से प्रति चरित्र भूमि के ऊपर की वजह से है,

4

एक अन्य विचार है कि XMLReader से कम पूरी तरह से गठित XML से निपटने के लिए और अधिक मजबूत हो सकता है। मैंने हाल ही में एक क्लाइंट बनाया है जो एक एक्सएमएल स्ट्रीम का उपभोग करता है, लेकिन स्ट्रीम में कुछ तत्वों में निहित यूआरआई में विशेष वर्ण नहीं बचते थे। XMLDocument और XPathDocument ने XML को लोड करने से इंकार कर दिया, जबकि XMLReader का उपयोग करके मैं स्ट्रीम से आवश्यक जानकारी निकालने में सक्षम था।

संबंधित मुद्दे