2015-01-07 3 views
0

При поиске некоторых инструментов для профилирования для XSLT я столкнулся с сообщением this. Поскольку многие люди предлагали просто опубликовать код и предложили дать отзыв об этом, мне было интересно, может ли кто-нибудь дать мне некоторую обратную связь по моему. Я пробовал это (http://www.saxonica.com/documentation/#!using-xsl/performanceanalysis), но выходной html не очень подробный.оптимизация кода XSLT

Я новичок в XSLT и обычно работаю с python/perl, где поддержка регулярных выражений намного лучше (однако я не исключаю, что это просто мое самое основное понимание XSLT). Однако для целей этого проекта мне пришлось работать с XSLT. Может быть, я заставляю его делать что-то очень неестественно. Любые комментарии - в особенности, в частности, но что-то еще приветствуется, как хотелось бы узнать - приветствуются!

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"> 

<xsl:template name="my_terms"> 

<xsl:variable name="excludes" select="not (codeblock or draft-comment or filepath or shortdesc or uicontrol or varname)"/> 

<!-- leftover example of how to work with excludes var --> 
<!--<xsl:if test=".//*[$excludes]/text()[contains(.,'access management console')]"><li class="prodterm"><b>PB QA:access management console should be "AppCenter"</b></li></xsl:if>--> 


<!-- Loop through all sentences and check for deprecated stuff --> 
<xsl:for-each select=".//*[$excludes]/text()"> 
    <xsl:variable name="sentenceList" select="tokenize(., '[\.!\?:;]\s+')"/> 
    <xsl:variable name="segment" select="."/> 

    <!-- main sentence loop --> 
    <xsl:for-each select="$sentenceList"> 
     <xsl:variable name="sentence" select="."/> 
     <!-- very rudimentary sentence length check --> 
     <xsl:if test="count(tokenize(., '\W+')) &gt; 30"> <li class="prodterm"><b>Sentence too long:</b> <xsl:value-of select="."/></li></xsl:if> 

     <!-- efforts to flag the shady case of the gerund --> 
     <xsl:if test="matches(., '\w+ \w+ing (the|a)')"> 
      <!-- some extra checks to weed out the false positives --> 
      <xsl:if test="not(matches(., '\b(on|about|for|before|while|when|after|by|a|the|an|some|all|every) \w+ing (the|a)', '!i')) and not(matches(., 'during'))"> 
       <li class="prodterm"><b>Possible unclear usage of gerund. If so, consider rewriting:</b> <xsl:value-of select="."/></li> 
      </xsl:if> 
     </xsl:if> 

     <!-- comma's after certain starting phrases --> 
     <xsl:if test="matches(., '^\s*Therefore[^,]')"><li class="prodterm"><b>Use a comma after starting a sentence with 'Therefore':</b> <xsl:value-of select="."/></li></xsl:if> 
     <xsl:if test="matches(., '^\s*(If you|Before|When)[^,]+$')"><li class="prodterm"><b>Use a comma after starting a sentence with 'Before', 'If you' or 'When':</b> <xsl:value-of select="."/></li></xsl:if> 

     <!-- experimenting with phrasal verbs (if there are a lot of verbs in phrasalVerbs.xml, it will be better to have this as the main loop (and do it outside the sentence loop)) --> 
     <xsl:for-each select="document('phrasalVerbs.xml')/verbs/verb[matches($sentence, concat('.* ', ./@text, ' .*'))]"> 
      <xsl:variable name="verbPart" select="."/> 
      <xsl:for-each select="$verbPart/particles/particle/@text[matches($sentence, .) and not(matches($sentence, concat($verbPart/@text, ' ', .)))]"> 
       <xsl:variable name="particle" select="."/> 
       <li class="prodterm"><b>Separated phrasal verb found in:</b> <xsl:value-of select="$sentence"/></li>  
      </xsl:for-each> 
     </xsl:for-each> 


     <!-- checking if conditionals (should be followed by then) --> 
     <xsl:if test="matches($sentence, '^\s*If\b', '!i') and not(matches($sentence, '\bthen\b', '!i'))"><li class="prodterm"><b>Conditional If found, but no then:</b> <xsl:value-of select="."/></li></xsl:if> 


     <!-- very dodgy way of detecting passive voice --> 
     <!--<xsl:if test="matches($sentence, '\b(are|can be|must be) \w+ed\b', '!i')"><li class="prodterm"><b>PB QA:Possible passive voice. If so, consider using active voice for:</b> <xsl:value-of select="."/></li></xsl:if>--> 


     <xsl:for-each select='document("generalDeprecatedTermsAndPhrases.xml")/terms/dt'> 
      <xsl:variable name="pattern" select="./@pattern"/> 
      <xsl:variable name="message" select="./@message"/> 
      <xsl:variable name="regexFlag" select="./@regexFlag"/> 

      <!-- <xsl:if test="matches($sentence, $pattern, $regexFlag)"> --> 
      <xsl:if test="matches($sentence, concat('(^|\W)', $pattern, '($|\W)'), $regexFlag)"> <!-- This is the work around for not being able to use \b when variable is passed on inside matches() --> 
       <li class="prodterm"><b><xsl:value-of select="$message"/> in: </b> <xsl:value-of select="$sentence"/> </li> 
      </xsl:if> 
     </xsl:for-each> 


    </xsl:for-each> 
</xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

Чтобы получить представление о том, раздели вниз версия моего «generalDeprecatedTermsAndPhrases.xml» выглядит следующим образом:

<dt pattern='to be able to' message="Use 'to' instead of 'to be able to'" regexFlag="i"></dt> 

</terms> 

ответ

0

причина того, что профиль Саксон не очень подробно, что ваш код поэтому монолит: это все в одном большом большом правиле шаблона.

Однако монолитный сам по себе не является причиной каких-либо проблем с производительностью.

Первое наблюдение является проблемой функциональности: ваша переменная

<xsl:variable name="excludes" select="not (codeblock or draft-comment or filepath or shortdesc or uicontrol or varname)"/> 

не делать то, что вы думаете. Он оценивается с узлом корневого документа как элементом контекста, а его значение является логическим, которое является истинным, если самый внешний элемент имеет имя, которое не является одним из перечисленных. Поэтому я думаю, что ваш xsl: for-each, который использует [$ excludes] в качестве предиката, применяется ко всем элементам, тогда как я подозреваю, что вы намеревались применить его к выбранным элементам. Я не знаю, насколько это влияет на производительность.

Основное влияние на производительность будет стоить оценка регулярных выражений. Лучший способ узнать, какие из них вызывают проблему, - это измерить влияние их удаления один за другим. Когда вы изолируете проблему, может возникнуть способ перезаписи регулярного выражения, чтобы сделать его более эффективным (например, избегая обратного отслеживания).

+0

Спасибо, приятно знать, что это исключает работу. Я рассматривал переписывание, чтобы профайлер дал более подробное изображение. Но сначала я проверю регулярные выражения, спасибо за указатели! – Igor

+0

Смешные детали; когда я читал ваше имя под вашим сообщением, он звонил в колокольчик, но больше не думал об этом. До сих пор, когда я понял, что у меня есть моя книга («XSLT 2nd edition, справочник программиста»), лежащий на моем столе здесь. Поэтому я постоянно смотрю на твое лицо (ну, я предполагаю, что это твое лицо на обложке). Большая книга, уже помогала мне в ряде случаев! – Igor

Смежные вопросы