2011-12-31 51 views
1

我们有以下经典的asp代码可以读取xml文件,当有超过10个并发请求到该页面时,它显示的性能很差,有人能够找出性能问题在此代码(我们知道的这是使用FileSystemObject的一个问题,但我们并没有为它的替代品!):如何优化这个从xml文件中读取的代码

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 

UPDATE:我放置了一个计时器来显示读取xml文件的函数的执行时间,发现在生产服务器上需要大约3秒钟,而在我的PC上需要不到1秒钟的时间!这是什么意思?我迷路了。

回答

3

显式的选项

如果你的脚本不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

在那里你可以得到一些真正的性能比较完善的区域是缓存在APPLI 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

我不认为stripHTMLtags的原因,在这里它的身体:功能stripHTMLtags(HTMLstring) \t设置RegularExpressionObject =新的RegExp \t随着RegularExpressionObject \t .Pattern = “<[^>] +>” \t .IgnoreCase =真 \t。环球=真 \t尾随着 \t stripHTMLtags = RegularExpressionObject.Replace(HTMLstring, “”) \t设置RegularExpressionObject =什么 端功能 – Cassini 2012-01-02 07:08:14

+0

@Cassini:评论是不要把代码的好地方。请编辑您的问题,并在其中包含“stripHTMLTags”的代码。 – AnthonyWJones 2012-01-02 13:10:41

+0

编辑...正如你可以看到它使用reguler表达式。 – Cassini 2012-01-02 17:33:29

0

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

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

请确保您使用的版本号为MSXML 3.0或更高版本以使用此方法。

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

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

+0

不可能,因为我们有成千上万个读取的xml文件。我已经试过msxml版本6的代码,但有很多问题 – Cassini 2011-12-31 14:27:43

+0

@Cassini - 如果你不能缓存文件,你可能不得不使用数据库来存储它们。 – Oded 2011-12-31 14:29:06

+0

@Cassini - 你有版本6安装?您可以使用3.0,4.0代替。 – Oded 2011-12-31 14:31:26