2008-10-22 11 views
9

मैं एक सहायक अभियंता हूं और हमारी कंपनी का उत्पाद XSLT आउटपुट को अनुकूलित करने के लिए बदल देता है।एक्सएसएलटी रूपांतरण क्षमता

मैंने इस उद्देश्य के लिए एक एक्सएसएल रूपांतरण किया है। यह ठेठ आकार (कई 100k) की स्रोत फ़ाइलों के लिए अच्छी तरह से काम करता है, लेकिन कभी-कभी वास्तव में एक विशाल (10 एम) स्रोत फ़ाइल आती है। ऐसे मामले में, आउटपुट उत्पन्न नहीं होता है भले ही मैं इसे कई दिनों पीसने देता हूं।

एसडब्ल्यू इंजीनियरिंग टीम ने इसका परीक्षण किया और पाया कि प्रश्न में ट्रांसफॉर्म और बड़ी स्रोत फ़ाइल वास्तव में बहुत धीमी है (> दिन), यदि हमारे उत्पाद को नेट 1.1 में ट्रांसफॉर्म इंजन का उपयोग करने के लिए संकलित किया गया है, लेकिन यदि वे संकलित करते हैं यह .NET 2.0 के साथ, यह बहुत तेज है (लगभग 1-2 मिनट)।

दीर्घकालिक समाधान स्पष्ट रूप से है, अगली रिलीज के लिए प्रतीक्षा करें।

अल्प अवधि के लिए मैं निम्नलिखित सोच रहा हूं: 1) क्या एक्सएसएलटी इतना लचीला है कि एक ही परिणाम को प्राप्त करने के लिए अधिक कुशल और कम कुशल तरीके हैं? उदाहरण के लिए, क्या यह संभव है कि जिस तरह से मैंने एक्सएसएल को संरचित किया, ट्रांसफॉर्म इंजन को कई बार स्रोत फ़ाइल की शुरुआत से फिर से शुरू करना पड़ता है, जो लंबे समय तक और अधिक समय लेता है क्योंकि अगला परिणाम टुकड़ा आगे से आगे और आगे हो जाता है? (श्लेमेल द पेंटर), या 2) क्या यह अधिक निर्भर है कि ट्रांसफॉर्म इंजन xsl का अर्थ कैसे देता है?

यदि 2 मामला है, तो मैं xsl में सुधार करने की कोशिश करने में बहुत समय बर्बाद नहीं करना चाहता (मैं एक बड़ा xsl प्रतिभा नहीं हूं, मेरे लिए जो कुछ भी मैंने किया है, वह हासिल करना मुश्किल था ...)।

धन्यवाद!

+0

मैंने उस बारे में नहीं सुना था :) http://en.wikipedia.org/wiki/Schlemiel_the_painter%27s_Algorithm – wprl

+0

मैंने पहली बार इसे http://www.joelonsoftware.com/articles/fog0000000319.html पर सुना जो (अजीब loops) है मैं कैसे StackOverflow – KnomDeGuerre

उत्तर

3

यह निर्धारित करने के लिए एक नया खंड शुरू करने के लिए, मैं इस किया था?

निश्चित रूप से। आपके द्वारा चुने गए एल्गोरिदम ओ (एन) है और कार्यान्वयन भाषा के बावजूद, पर्याप्त संख्या में भाई बहनों के साथ बहुत धीमी होगी।

यहाँ एक कुशल एल्गोरिथ्म कुंजियों का उपयोग है:

solution1:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output method="text"/> 

<xsl:key name="kC1Value" match="@c1" use="."/> 

    <xsl:template match="/"> 
     <xsl:for-each select="*/x[generate-id(@c1) = generate-id(key('kC1Value',@c1)[1])]"> 

     <xsl:value-of select="concat('&#xA;',@c1)"/> 

     <xsl:for-each select="key('kC1Value',@c1)"> 
     <xsl:value-of select="'&#xA;'"/> 
     <xsl:for-each select="../@*[not(name()='c1')]"> 
      <xsl:value-of select="concat(' ', .)"/> 
     </xsl:for-each> 
     </xsl:for-each> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

दुर्भाग्य से, XslTransform (नेट 1.1) generate-id() समारोह के एक बेहद अक्षम कार्यान्वयन है।

Solution2:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output method="text"/> 

<xsl:key name="kC1Value" match="@c1" use="."/> 

    <xsl:template match="/"> 
     <xsl:for-each select="*/x[count(@c1 | key('kC1Value',@c1)[1]) = 1]"> 

     <xsl:value-of select="concat('&#xA;',@c1)"/> 

     <xsl:for-each select="key('kC1Value',@c1)"> 
     <xsl:value-of select="'&#xA;'"/> 
     <xsl:for-each select="../@*[not(name()='c1')]"> 
      <xsl:value-of select="concat(' ', .)"/> 
     </xsl:for-each> 
     </xsl:for-each> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

जब निम्नलिखित छोटे XML दस्तावेज़ पर लागू:

<t> 
<x c1="1" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="1" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="1" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="1" c2="1" c3="1" c4="0" c5="0"/> 
<x c1="2" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="2" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="2" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="2" c2="1" c3="1" c4="0" c5="0"/> 
<x c1="3" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="3" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="3" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="3" c2="1" c3="1" c4="0" c5="0"/> 
<x c1="3" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="3" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="3" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="3" c2="1" c3="1" c4="0" c5="0"/> 
<x c1="4" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="4" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="4" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="4" c2="1" c3="1" c4="0" c5="0"/> 
<x c1="5" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="5" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="5" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="5" c2="1" c3="1" c4="0" c5="0"/> 
<x c1="5" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="5" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="6" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="6" c2="1" c3="1" c4="0" c5="0"/> 
<x c1="6" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="6" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="6" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="6" c2="1" c3="1" c4="0" c5="0"/> 
<x c1="7" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="7" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="7" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="7" c2="1" c3="1" c4="0" c5="0"/> 
<x c1="8" c2="0" c3="0" c4="0" c5="0"/> 
<x c1="8" c2="0" c3="1" c4="0" c5="0"/> 
<x c1="8" c2="2" c3="0" c4="0" c5="0"/> 
<x c1="8" c2="1" c3="1" c4="0" c5="0"/> 
</t> 

दोनों समाधान वांछित परिणाम का उत्पादन किया:

निम्नलिखित तेजी XslTransform साथ हो सकता है

1 
    0 0 0 0 
    0 1 0 0 
    2 0 0 0 
    1 1 0 0 
2 
    0 0 0 0 
    0 1 0 0 
    2 0 0 0 
    1 1 0 0 
3 
    0 0 0 0 
    0 1 0 0 
    2 0 0 0 
    1 1 0 0 
    0 0 0 0 
    0 1 0 0 
    2 0 0 0 
    1 1 0 0 
4 
    0 0 0 0 
    0 1 0 0 
    2 0 0 0 
    1 1 0 0 
5 
    0 0 0 0 
    0 1 0 0 
    2 0 0 0 
    1 1 0 0 
    0 0 0 0 
    0 1 0 0 
6 
    2 0 0 0 
    1 1 0 0 
    0 0 0 0 
    0 1 0 0 
    2 0 0 0 
    1 1 0 0 
7 
    0 0 0 0 
    0 1 0 0 
    2 0 0 0 
    1 1 0 0 
8 
    0 0 0 0 
    0 1 0 0 
    2 0 0 0 
    1 1 0 0 

उपर्युक्त छोटी एक्सएमएल फ़ाइल से मैंने प्रत्येक तत्व 6250 बार प्रतिलिपि बनाकर 10 एमबी एक्सएमएल फ़ाइल उत्पन्न की है (एक और एक्सएसएलटी परिवर्तन का उपयोग कर :))।

solution1: 3.3sec

10 एमबी xml फ़ाइल के साथ और XslCompiledTransform (नेट 2.0+) के साथ

दो समाधान निम्न परिवर्तन बार किया था।
समाधान 2: 2.8sec।

XslTransform (.Net 1.1) समाधान 2 के साथ 1622sec के लिए चलाया गया; यह लगभग 27 मिनट है।

+1

मैंने अभी देखा है कि और निर्देश प्रदर्शित नहीं किए जा रहे थे - अब इसे सही किया गया है। –

5

मैं नेट कार्यान्वयन से परिचित नहीं हूँ, लेकिन आपको कुछ बातों का आप सामान्य रूप में कर सकते हैं बड़े दस्तावेजों के प्रसंस्करण में तेजी लाने के लिए कर रहे हैं:

  • बचें का उपयोग कर "//" xPath अभिव्यक्ति में जब तक बिलकुल जरूरी।
  • यदि आपको केवल एक्सपैथ अभिव्यक्ति से मेल खाने वाले पहले या एकमात्र तत्व की आवश्यकता है, तो "[1]" क्वालीफायर का उपयोग करें, उदा। "// आइफ्रेम [1]"। कई प्रोसेसर इसके लिए अनुकूलन लागू करते हैं।
  • जब भी संभव हो, विशाल एक्सएमएल इनपुट से निपटने पर, देखें कि क्या आप एक डीओएम-आधारित पार्सर के बजाय स्ट्रीम-आधारित पार्सर (एसएएक्स की तरह) के आसपास समाधान तैयार कर सकते हैं।
4

आम तौर पर, यदि आप प्रसंस्करण समय बनाम इनपुट आकार में गैर-रैखिक वृद्धि देखते हैं, तो आपको ढांचे से अधिक अपने कोड पर संदेह करना चाहिए। लेकिन चूंकि उपकरण .NET 2.0 के साथ संकलित होने पर समस्या दूर हो जाती है, इसलिए सभी दांव बंद हैं।

XSLT के साथ, यह एक गैर रेखीय प्रदर्शन वक्र बनाने के लिए मुश्किल है यदि आप अपने सभी पार्स सीधे टेम्पलेट मैचों के साथ कार्य करें:

<xsl:template match="foo"> 
    <!--OUTPUT--> 
    <xsl:apply-templates/> 
    <!--OUTPUT--> 
</xsl:template> 

<xsl:template match="bar"> 
    <!--OUTPUT--> 
    <xsl:apply-templates/> 
    <!--OUTPUT--> 
</xsl:template> 

वेतन सावधान ध्यान में कहीं भी आप सहारा हो सकता है <xsl:for-each> पार्सिंग के लिए करने के लिए ; टेम्पलेट मैचों वही परिणाम प्राप्त करने के लिए लगभग हमेशा एक बेहतर तरीका है।

इस प्रदर्शन समस्या का निवारण करने का एक तरीका है एक बार में अपने एक्सएसएलटी एक टेम्पलेट-मैच को फिर से बनाना, प्रत्येक मैच जोड़ने के बाद प्रसंस्करण समय का परीक्षण करना। आप इस मैच के साथ शुरू हो सकता है:

<xsl:template match="*"> 
    <xsl:copy>     <!--Copy node     --> 
    <xsl:copy-of select="@*"/> <!--Copy node attributes   --> 
    <xsl:apply-templates /> <!--Process children    --> 
    </xsl:copy> 
</xsl:template> 

इस से मेल खाते हैं और एक समय में प्रत्येक नोड, एक कॉपी, किसी नए दस्तावेज़ में होगा।यह प्रसंस्करण समय बनाम इनपुट आकार में एक गैर-रैखिक वृद्धि प्रदर्शित नहीं करना चाहिए (यदि ऐसा होता है, तो समस्या आपके एक्सएसएलटी कोड के साथ नहीं है)।

जैसे ही आप अपने एक्सएसएलटी को फिर से बनाते हैं, यदि आप एक टेम्पलेट-मैच जोड़ते हैं जो अचानक प्रदर्शन को मारता है, तो टेम्पलेट के अंदर प्रत्येक ब्लॉक को टिप्पणी करें। फिर, एक समय में एक ब्लॉक को विघटित करें, प्रत्येक पुनरावृत्ति प्रसंस्करण समय का परीक्षण करें, जब तक आपको समस्या का कारण बनने वाले ब्लॉक को न मिल जाए।

2

एक चीज दुनिया की जांच यह है कि यदि आपका एक्सएसएलटी एक्सएमएल दस्तावेज़ के अन्य हिस्सों में बहुत कुछ देखता है, यानी आप एक संदर्भ नोड में हैं और दस्तावेज़ के किसी अन्य भाग या यहां तक ​​कि किसी अन्य दस्तावेज़ में एक मूल्य तलाशते हैं। यदि आप ऐसा कर रहे हैं तो यह प्रदर्शन को काफी कठिन बना सकता है और आपको xsl:key और इसके लिए मुख्य कार्य का उपयोग करने पर विचार करना चाहिए। यह प्रोसेसर को प्रश्न में डेटा पर फास्ट लुकअप इंडेक्स को लागू करने के लिए कहता है।

मैं एक बार एक एक्सएसएलटी का निर्माण कर रहा था जिसमें दौड़ने के लिए 8 घंटे लग गए (बहुत सारे क्रॉस संदर्भों के साथ) और उपयोग कुंजी पर स्विच करने से यह काफी तेज गति प्रदान करता है।

+0

धन्यवाद के बारे में पता चला! मेरे पास कोई एक्सएसएल नहीं है: मेरी एक्सएसएल में कुंजी। – KnomDeGuerre

1

अपनी समस्या को देखने पर, मुझे इसके बारे में माइक्रोसॉफ्ट में एक केबी मिला। आप इसे here देख सकते हैं।

वे कहते हैं कि .NET 1 में एक्सएसएलटी रूपांतरण में प्रदर्शन के साथ कुछ समस्याएं हैं और वे त्वरित समाधान प्रदान कर सकते हैं।

यदि आप समस्या का निवारण करने का प्रयास करना चाहते हैं, तो एक एक्सएसएलटी प्रोफाइलर here उपलब्ध है।

अन्यथा, आप देख सकते हैं कि एक्सएसएलटी (link) के साथ गति समस्याओं को अनुकूलित करने के लिए माइक्रोसॉफ्ट वेबसाइट पर कौन से लिंक दिए गए हैं।

<xsl:if test="@TheFirstCol>preceding-sibling::*[1]/@TheFirstCol" 

इस एक बहुत या फिर से यात्रा के कारण हो सकता है:

+0

धन्यवाद! कोई एक्सएसएल: हालांकि मेरे ट्रांसफॉर्म में कुंजी। – KnomDeGuerre

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