2011-12-31 77 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