سؤال

أنا أستخدم رمز XSL 2.0 أدناه للعثور على معرفات العقد النصية التي تحتوي على قائمة المؤشرات التي أعطيها كمدخلات. يعمل الرمز بشكل مثالي ولكن من حيث الأداء ، فإنه يستغرق وقتًا طويلاً للملفات الضخمة. حتى بالنسبة للملفات الضخمة إذا كانت قيم الفهرس صغيرة ، فإن النتيجة سريعة في عدد قليل من MS. أنا أستخدم معالج Java Saxon9he لتنفيذ XSL.

<xsl:variable name="insert-data" as="element(data)*"> 
  <xsl:for-each-group 
    select="doc($insert-file)/insert-data/data" 
    group-by="xsd:integer(@index)"> 
    <xsl:sort select="current-grouping-key()"/> 
    <data 
      index="{current-grouping-key()}" 
      text-id="{generate-id(
        $main-root/descendant::text()[
          sum((preceding::text(), .)/string-length(.)) ge current-grouping-key()
        ][1]
      )}"> 
      <xsl:copy-of select="current-group()/node()"/> 
    </data> 
  </xsl:for-each-group> 
</xsl:variable> 

في الحل أعلاه إذا كانت قيمة الفهرس ضخمة جدًا ، فالقول 270962 ، فإن الوقت المستغرق لـ XSL للتنفيذ هو 83427 مللي ثانية. في الملفات الضخمة إذا كانت قيمة الفهرس ضخمة يقول 4605415 ، 4605431 يستغرق تنفيذها عدة دقائق. يبدو أن حساب المتغير "إدراج البيانات" يستغرق وقتًا على الرغم من أنه متغير عالمي ويتم حسابه مرة واحدة فقط. هل يجب أن يكون XSL معالجًا أم المعالج؟ كيف يمكنني تحسين أداء XSL.

هل كانت مفيدة؟

المحلول

أعتقد أن المشكلة هي توليد text-id, ، أي التعبير

generate-id(
    $main-root/descendant::text()[
      sum((preceding::text(), .)/string-length(.)) ge current-grouping-key()
    ][1]
  )

من المحتمل أن تقوم بإعادة حساب الكثير من المبالغ هنا. أعتقد أن أسهل مسار هنا هو عكس نهجك: تكرار عبر العقد النصية في المستند ، وتجميع طول السلسلة حتى الآن ، والإخراج data العناصر في كل مرة جديدة @index تم الوصول إليه. يوضح المثال التالي النهج. لاحظ أن كل فريد @index ويتم زيارة كل عقدة نصية مرة واحدة فقط.

<xsl:variable name="insert-doc" select="doc($insert-file)"/>

<xsl:variable name="insert-data" as="element(data)*"> 
    <xsl:call-template name="calculate-data"/>
</xsl:variable>

<xsl:key name="index" match="data" use="xsd:integer(@index)"/>

<xsl:template name="calculate-data">
    <xsl:param name="text-nodes" select="$main-root//text()"/>
    <xsl:param name="previous-lengths" select="0"/>
    <xsl:param name="indexes" as="xsd:integer*">
        <xsl:perform-sort 
            select="distinct-values(
                    $insert-doc/insert-data/data/@index/xsd:integer(.))">
            <xsl:sort/>
        </xsl:perform-sort>
    </xsl:param>
    <xsl:if test="$text-nodes">
        <xsl:variable name="total-lengths" 
            select="$previous-lengths + string-length($text-nodes[1])"/>
        <xsl:choose>
            <xsl:when test="$total-lengths ge number($indexes[1])">
                <data 
                    index="{$indexes[1]}" 
                    text-id="{generate-id($text-nodes[1])}">
                    <xsl:copy-of select="key('index', $indexes[1], 
                                             $insert-doc)"/> 
                </data>
                <!-- Recursively move to the next index. -->
                <xsl:call-template name="calculate-data">
                    <xsl:with-param
                        name="text-nodes"
                        select="$text-nodes"/>
                    <xsl:with-param
                        name="previous-lengths" 
                        select="$previous-lengths"/>
                    <xsl:with-param
                        name="indexes" 
                        select="subsequence($indexes, 2)"/>
                </xsl:call-template>                    
            </xsl:when>
            <xsl:otherwise>
                <!-- Recursively move to the text node. -->
                <xsl:call-template name="calculate-data">
                    <xsl:with-param 
                        name="text-nodes" 
                        select="subsequence($text-nodes, 2)"/>
                    <xsl:with-param
                        name="previous-lengths" 
                        select="$total-lengths"/>
                    <xsl:with-param 
                        name="indexes" 
                        select="$indexes"/>
                </xsl:call-template>                    
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top