如何优化从xml文件读取的代码

时间:2011-12-31 14:16:02

标签: asp-classic msxml

我们还有以下从xml文件中读取的经典asp代码,当该页面有超过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 个答案:

答案 0 :(得分:3)

选项明确

如果您的脚本不以Option Explict开头,请立即进行更改。然后修复出现的所有编译错误。并没有帮助提高性能,但是当我看到证据证明这个最大的脚本错误正在制作时,它只需要提及。

<强> FileSystemObject的

我怀疑性能问题是FileSystemObject的结果,你所做的只是创建一个实例并测试文件的存在性。这几乎不会引起问题。

话虽如此,我还是会放弃FileSystemObject。如果出现问题,只需让脚本抛出错误。使用IIS管理器将500.100状态代码映射到一个ASP页面,该页面呈现一个友好的&#34;发生了一些不好的事情&#34;页面给用户。 (500.100是脚本抛出异常时的请求状态)。还要测试DOM load方法的布尔结果,当解析错误也不为0时抛出错误。这样你就可以将所有丑陋的异常处理交给500.100处理页面,并且你的代码可以保持干净,只需处理代码的名义路径。

整理路径

也许你有正当理由使用&#34; //&#34;你的路径很多(但不一致),但我会假设没有,所以我们可以简化一些路径:

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发生的地方,这通常是性能问题的原因。

答案 1 :(得分:0)

您可以在应用程序启动时将XML加载到字符串中,并将其存储在Application对象中。

然后,不使用source.load,而是使用source.loadXML和此字符串 - 您将不再访问文件系统。请参阅loadXML的文档。

确保使用MSXML 3.0或更高版本来使用此方法。

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

更新 - 看到你有成千上万的这些文件并且你认为将它们存储在Application对象的内存中是不可行的,你应该使用数据库来处理你看到的并发问题。将键入的文件的内容存储为类似当前文件名/路径的内容 - 从数据库中检索它们并使用相同的loadXML机制加载到文档中。