Как оптимизировать этот код, который читает из XML-файла - PullRequest
1 голос
/ 31 декабря 2011

У нас есть следующий классический asp-код, который читает из XML-файла, он показывает низкую производительность, когда к этой странице более 10 одновременных запросов, может кто-нибудь выяснить проблему производительности в этом коде (мы знаем одну из проблемы, которые используют fileSystemObject, но у нас нет альтернатив для этого!):

set filesys=server.CreateObject("Scripting.FileSystemObject")
if filesys.FileExists(sourcefile) then  
 set source = Server.CreateObject("Msxml2.DOMDocument")
 source.validateOnParse = false
 source.resolveExternals = false
 source.preserveWhiteSpace = false
 source.load(sourcefile)  

If source.ParseError.errorCode <> 0 Then
   str_head=source.selectSingleNode("/LIST/ITEM/NEWSITEM/HEADLINE//").text

   str_by=source.selectSingleNode("//LIST//ITEM//NEWSITEM//PROVIDER//").text

   News_date_orig = source.selectSingleNode("/LIST/ITEM/NEWSITEM/CREATED//").text
   str_date= formatdatetime(source.selectSingleNode("//LIST//ITEM//NEWSITEM//CREATED//").text,1)
   set bodyNode=source.selectSingleNode("/LIST/ITEM/NEWSITEM//BODY//")
   styleFile=Server.MapPath("/includes/xsl/template.xsl")
   Set style = Server.CreateObject("Msxml2.DOMDocument")
   style.validateOnParse = false
   style.resolveExternals = false
   style.preserveWhiteSpace = false
   style.load(styleFile)
   news_full = bodyNode.transformNode(style)
   if len(news_full) < 10 then
   news_full = str_abstract 
end if 
DiscriptionKeyWord = stripHTMLtags(news_full)
DiscriptionKeyWord=StrCutOff(DiscriptionKeyWord, 200, "...")
headerTitle=str_head
Set style=nothing
Set source = nothing
end if
set filesys= nothing

Следующая функция stripHTMLtags:

Function stripHTMLtags(HTMLstring) 
  Set RegularExpressionObject = New RegExp 
  With RegularExpressionObject 
   .Pattern = "<[^>]+>" 
   .IgnoreCase = True 
   .Global = True 
  End With 
  stripHTMLtags = RegularExpressionObject.Replace(HTMLstring, "") 
  Set RegularExpressionObject = nothing 
End Function

ОБНОВЛЕНИЕ: Я установил таймер, чтобы показать время выполнения функции, которая читает файл XML, и обнаружил, что на рабочем сервере это занимает около 3 секунд, а на моем компьютере - менее 1 секунды! Что это значит ?! Я потерян.

Ответы [ 2 ]

3 голосов
/ 01 января 2012

Вариант Явный

Если ваши сценарии не начинаются с Option Explict, сделайте это сейчас. Затем исправьте все ошибки компиляции, которые появляются. Производительность не помогает, но когда я вижу доказательства того, что совершается эта самая большая из ошибок скриптинга, это просто необходимо упомянуть.

FileSystemObject

Я сомневаюсь, что проблема с производительностью является результатом FileSystemObject, все, что вы делаете, это создаете экземпляр и проверяете наличие файла. Это вряд ли может вызвать проблемы.

Сказав, что я все равно откажусь от FileSystemObject. Просто позвольте сценарию выдать ошибку, если есть проблема. Используйте диспетчер IIS, чтобы сопоставить коды состояния 500.100 с ASP-страницей, которая представляет дружественную страницу «Что-то плохое случилось» для пользователя. (500.100 - это состояние запроса, когда скрипт выдает исключение). Также проверьте логический результат метода DOM load, выдавайте ошибку, когда ошибка разбора также не равна 0. Таким образом, вы передаете всю ужасную обработку исключений на страницу обработки 500.100, и ваш код может оставаться чистым, просто имея дело с номинальным путем кода.

привести в порядок дорожки

Возможно, есть причина, по которой вы часто используете "//" в своих путях (но непоследовательно), но я собираюсь предположить, что нет, поэтому мы можем упростить некоторые пути:

Dim newsItem: Set newsItem = source.selectSingleNode("/LIST/ITEM/NEWSITEM")

Dim str_head: str_head = newsItem .selectSingleNode("HEADLINE").text 

Dim str_by: str_by = newsItem .selectSingleNode("PROVIDER").text 

Dim News_date_orig: News_date_orig = newsItem .selectSingleNode("CREATED").text 
Dim str_date: str_date = formatdatetime(News_date_orig, 1)

Dim bodyNode: Set bodyNode = newsItem.selectSingleNode("BODY") 

Кэш XSLTemplate

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

Dim xslTemplate
If IsObject(Application("xsl_template")) Then
    Set xslTemplate = Application("xsl_template")
Else   
    Set style = Server.CreateObject("Msxml2.FreeThreadedDOMDocument.3.0")
    style.async = false    
    style.validateOnParse = false    
    style.resolveExternals = false    
    style.preserveWhiteSpace = false    
    style.load Server.MapPath("/includes/xsl/template.xsl")

    Set xslTemplate = CreateObject("MSXML2.XSLTemplate.3.0")
    xslTemplate.stylesheet = xsl
    Set Application("template") = xslTemplate
End If

Dim xslProc: Set xslProc = xslTemplate.createProcessor()
xslProc.input = bodyNode

xslProc.transform()   
news_full = xslProc.output

Усилия по чтению, анализу и компиляции XSL-преобразования выполняются только один раз за все время жизни приложения.

Наиболее вероятный виновник

Если честно, я подозреваю, что наиболее вероятным виновником является stripHTMLtags. Это звучит как целая нагрузка обработки строк, а производительность обработки строк VBScript низкая. Особенно плохо, когда код неправильно ориентирован на знание ограничений производительности обработки строк (например, чрезмерных и повторяющихся конкатенаций строк). Скорее всего, именно там встречается наиболее актуальный VBScript, который часто является причиной проблем с производительностью.

0 голосов
/ 31 декабря 2011

Вы можете загрузить XML в строку при запуске приложения и сохранить его в объекте Application.

Тогда, вместо использования source.load, используйте source.loadXML с этой строкой - вы не будетеполучать доступ к файловой системе больше.См. Документацию для loadXML.

Убедитесь, что вы используете версию MSXML 3.0 или более позднюю, чтобы использовать этот метод.

Server.CreateObject("Msxml2.DOMDocument.6.0")

Обновление - поскольку у вас есть тысячи таких файлов, и вы считаете, что невозможно сохранить их в памяти в объекте Application, вам следует использовать базу данных для решения проблем параллелизма, которые вы видите.Сохраните содержимое файлов, привязанных к чему-то вроде их текущего имени файла / пути - извлеките их из базы данных и загрузите в документ, используя тот же механизм loadXML.

...