明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

二108條改善 ASP 性能與外觀的技巧(8-14)

[摘要]技巧 8:遲一點獲得資源,早一點釋放資源 技巧 9:進程外執(zhí)行過程以性能換取可靠性 技巧 10:使用顯式選項 技巧 11:在子例程和函數(shù)中使用局部變量 技巧 12:將經(jīng)常使用的數(shù)據(jù)復制到腳本變量中 技巧 13:避免重新確定數(shù)組的維數(shù) 技巧 14:使用響應緩沖 技巧 8:遲一點獲得資源,早一點釋放資...
技巧 8:遲一點獲得資源,早一點釋放資源
技巧 9:進程外執(zhí)行過程以性能換取可靠性
技巧 10:使用顯式選項
技巧 11:在子例程和函數(shù)中使用局部變量
技巧 12:將經(jīng)常使用的數(shù)據(jù)復制到腳本變量中
技巧 13:避免重新確定數(shù)組的維數(shù)
技巧 14:使用響應緩沖

技巧 8:遲一點獲得資源,早一點釋放資源
這里是一個小技巧供您參考。一般來說,最好遲一點獲得資源,早一點釋放資源。這適用于 COM 對象以及文件句柄和其它資源。

這種優(yōu)化方法主要用于 ADO 連接和記錄集。當您使用完記錄集,比方說在顯示一個表及其數(shù)據(jù)之后,應立即釋放它,而不是等到頁面結(jié)束時再釋放。將 VBScript 變量設(shè)置為 Nothing 是最好的做法。不要讓記錄集超出作用域之外。而且,要釋放任何相關(guān)的 Command 或 Connection 對象(在將記錄集或連接設(shè)置為 = Nothing 之前,不要忘記調(diào)用 Close())。這會縮短數(shù)據(jù)庫必須為您準備資源的時間,并盡快釋放數(shù)據(jù)庫到連接池的連接。

技巧 9:進程外執(zhí)行過程以性能換取可靠性
ASP 和 MTS/COM+ 兩者都有配置選項,可使您兼顧可靠性和性能。當建立和部署應用程序時,應知道如何兼顧兩者的性能。

ASP 選項
可以配置 ASP 應用程序,以便以三種方法之一運行。在 IIS 5.0 中,引入了“隔離級”這一術(shù)語以說明這些選項。這三個隔離級分別是低級、中級和高級:

低級隔離。這在 IIS 的所有版本中都得到支持,且是最快的。它在 Inetinfo.exe 中運行 ASP,Inetinfo.exe 是主要 IIS 進程。如果 ASP 應用程序崩潰,IIS 也會崩潰。(要在 IIS 4.0 下重新啟動 IIS,Web 站點管理員應使用諸如 InetMon 之類的工具監(jiān)視站點,如果服務器發(fā)生故障,應啟用批處理文件以重新啟動服務器。IIS 5.0 引入了可靠的重新啟動,該方法可使發(fā)生故障的服務器自動重新啟動。)
中級隔離。IIS 5.0 引入了這個新的級別,它被稱為進程外級別,因為 ASP 在 IIS 進程之外運行。在中級隔離中,被配置作為中級隔離運行的所有 ASP 應用程序都共享一個進程空間。這就減少了在一臺服務器運行多個進程外 ASP 應用程序所需要的進程數(shù)量。中級 隔離是 IIS 5.0 中的默認隔離級別。
高級隔離。在 IIS 4.0 和 IIS 5.0 中支持這一級別,高級隔離也是進程外的。如果 ASP 崩潰,Web 服務器并不會崩潰。下次 ASP 請求時,ASP 應用程序就會自動重新啟動。在高級隔離中,配置作為 高級隔離運行的每個 ASP 應用程序都在其自有進程空間中運行。這樣做可保護 ASP 應用程序彼此之間不相互干擾。其缺點是它要求每個 ASP 應用程序都要有一個單獨的進程。當在一臺服務器上必須運行許多應用程序時,系統(tǒng)開銷就會大大增加。
哪個選項最好的呢?在 IIS 4.0 中,進程外運行將顯著降低性能。在 IIS 5.0 中,做了許多改進,將進程外運行 ASP 應用程序所產(chǎn)生的開銷降到最低限度。事實上,在絕大多數(shù)測試中,IIS 5.0 中的 ASP 進程外應用程序比 IIS 4.0 中的進程內(nèi)應用程序運行得更快。不管怎樣,在兩個平臺上,進程內(nèi)(低隔離級)性能最佳。但是,如果訪問率相對較低或最大吞吐量較低,低隔離級的優(yōu)勢不太明顯。因此,在您每一 Web 服務器每秒鐘需要數(shù)百或成千上萬頁面時,才會覺得有必要設(shè)置低隔離級。與往常一樣,應對多種配置進行測試,確定您要采取哪一種折衷方案。

注意 當您運行 ASP 進程外應用程序時(中級或高級隔離),它們在 NT4 中的 MTS 和在 Windows 2000 中的 COM+ 中運行。即,在 NT4 中它們在 Mtx.exe 中運行;而在 Windows 2000 中,它們在 DllHost.exe 中運行。您可以在任務管理器中看到這些進程在運行。您還可以看到 IIS 如何為進程外 ASP 應用程序配置 MTS 程序包或 COM+ 應用程序。

COM 選項
COM 組件也有三種配置選項,雖然與 ASP 選項不完全類似。COM 組件可以是“未配置的”、配置為庫應用程序或配置為服務器應用程序!拔磁渲玫摹币馑际侵附M件沒有注冊 COM+。組件將在調(diào)用程序的進程空間運行,那就是說,它們是“進程內(nèi)的”。庫應用程序也是進程內(nèi)的,但使用 COM+ 的服務,包括安全、事務和上下文支持。服務器應用程序被配置為在它們自有的進程空間內(nèi)運行。

您可以看到未配置的組件比庫應用程序略有一些優(yōu)勢。庫應用程序比服務器應用程序的性能優(yōu)點更大。這是因為庫應用程序與 ASP 在同一進程內(nèi)運行,而服務器應用程序在它們的自有進程內(nèi)運行。進程間的調(diào)用比進程內(nèi)調(diào)用開銷更大。而且,當在進程之間傳遞諸如記錄集之類的數(shù)據(jù)時,必須在兩個進程之間復制所有的數(shù)據(jù)。

陷阱!當使用 COM 服務器應用程序時,如果您在 ASP 和 COM 之間傳遞對象,要確保對象執(zhí)行“按值匯集”或 MBV。執(zhí)行 MBV 的對象將它們自己從一個進程復制到另一個進程。這比下面一種方法好,采用這種方法時,對象仍在創(chuàng)建者的進程中,另外一個進程反復地調(diào)用創(chuàng)建進程以使用該對象。切斷連接的 ADO 記錄集將“按值匯集”,連接的記錄集則不然。Scripting.Dictionary 不執(zhí)行 MBV,且不在進程之間傳遞。最后,VB 程序員請注意:MBV 不通過傳遞參數(shù) ByVal 獲得。MBV 由原始的組件作者執(zhí)行。

怎么辦?
如果讓我們建議一個兼顧性能與可靠性的合理配置,它們應是如下的配置:

在 IIS 4.0 中,使用 ASP 低隔離級別,使用 MTS 服務器程序包。
在 IIS 5.0 上,使用 ASP 的中隔離級,并使用 COM+ 庫應用程序。
這些是非常一般的原則,主機服務公司一般情況下以中或高隔離級運行 ASP,而單用途的 Web 服務器可以以低隔離級運行。衡量各種利弊,并自己決定哪個配置更能符合您的需要。

技巧 10:使用顯式選項
在 .asp 文件中應使用 Option Explicit。此指令放在 .asp 文件的最上面,它強制開發(fā)人員聲明要使用到的所有變量。許多程序員認為這種方法對于調(diào)試應用程序很有幫助,因為這種方法避免了鍵錯變量名和誤建新變量的可能性(例如,將 MyXMLString=) 錯寫成 MyXLMString=...。

更重要的一點也許是,聲明的變量比未聲明的變量速度更快。由此,腳本在運行時每次用到未聲明的變量時,按名稱引用它。另一方面,聲明的變量是有順序的,要么以編譯時間,要么以運行時間。以后,聲明的變量都按此順序引用。因為 Option Explicit 強制變量聲明,它能確保聲明所有變量,因此訪問的速度也很快。

技巧 11:在子例程和函數(shù)中使用局部變量
局部變量是那些在子例程和函數(shù)內(nèi)聲明的變量。在函數(shù)或子例程內(nèi),局部變量訪問比全局變量訪問更快。局部變量的使用也會使代碼更清晰,因此應盡量使用局部變量。

技巧 12:將經(jīng)常使用的數(shù)據(jù)復制到腳本變量中
當訪問 ASP 中的 COM 對象時,應將經(jīng)常使用的對象數(shù)據(jù)復制到腳本變量中。這樣做可減少 COM 方法調(diào)用,因為 COM 方法調(diào)用與訪問腳本變量相比,開銷相對較大。當訪問 Collection 和 Dictionary 對象時,這種技術(shù)也會減少開銷很大的查找。

一般來說,如果您打算不止一次訪問對象數(shù)據(jù),那么就應將數(shù)據(jù)放到腳本變量中。這種優(yōu)化的主要目標是 Request 變量(Form 和 QueryString 變量)。例如,您的站點可傳遞一個名為 UserID 的 QueryString 變量。假設(shè)此 UserID 在特定頁面上被引用 12 次。可以無須調(diào)用 Request(?UserID?) 12 次,而是在 ASP 頁面最上面將 UserID 指派到一個變量。然后在該頁面自始至終使用該變量。這樣就省去了 11 次 COM 方法調(diào)用。

實際上,訪問 COM 屬性或方法的開銷并沒有那么大。下面舉一個例子,說明某相當常見的代碼(從語法上講):

Foo.bar.blah.baz = Foo.bar.blah.qaz(1)
If Foo.bar.blah.zaq = Foo.bar.blah.abc Then ' ...


當此代碼運行時,下面是發(fā)生的情況:

變量 Foo 被解析為全局對象。
變量 bar 被解析為 Foo 的成員。這實際就是一次 COM 方法調(diào)用。
變量 blah 被解析為 Foo.bar 的成員。這又是一次 COM 方法調(diào)用。
變量 qaz 被解析為 foo.bar.blah 的成員。沒有錯,這還是一次 COM 方法調(diào)用。
調(diào)用 Foo.bar.blah.quaz(1)。再一次 COM 方法調(diào)用。懂了嗎?
再次執(zhí)行步驟 1 至步驟 3 以解析 baz。系統(tǒng)并不知道調(diào)用 qaz 是否改變對象模型,因此必須再次執(zhí)行步驟 1 至 3 以解析 baz。
將 baz 解析為 Foo.bar.blah 的成員。賦予屬性。
再次執(zhí)行步驟 1 至步驟 3 以解析 zaq。
再次執(zhí)行步驟 1 至步驟 3 以解析 abc。
正如您可看到的,效率相當差(且慢)。以 VBScript 寫此代碼的快速方法是:

Set myobj = Foo.bar.blah ' do the resolution of blah ONCE
Myobj.baz = myobj.qaz(1)
If Myobj.zaq = Myobj.abc Then '...


如果您使用 VBScript 5.0 或更高版本,您可以使用 With 語句寫此代碼:

With Foo.bar.blah
.baz = .qaz(1)
If .zaq = .abc Then '...
...
End With


注意此技巧也適用于 VB 程序設(shè)計。

技巧 13:避免重新確定數(shù)組的維數(shù)
應盡量避免 Redim 數(shù)組。就性能而言,如果計算機的物理內(nèi)存大小有限,最好將數(shù)組的初始維數(shù)設(shè)置為其最不利的情況 - 或?qū)⒕S數(shù)設(shè)置為其最佳的情況,然后再按需要重新確定維數(shù)。這并非意味著,如果知道您不需要內(nèi)存時,就隨便分配幾兆字節(jié)的內(nèi)存。

下面的代碼給您顯示使用 Dim 和 Redim 不當?shù)那樾巍?

<%
Dim MyArray()
Redim MyArray(2)
MyArray(0) = ?hello?
MyArray(1) = ?good-bye?
MyArray(2) = ?farewell?
...
' some other code where you end up needing more space happens, then ...
Redim Preserve MyArray(5)
MyArray(3) = ?more stuff?
MyArray(4) = ?even more stuff?
MyArray(5) = ?yet more stuff?
%>


最好一開始就將數(shù)組的初始大小 Dim 正確(在本例中,是 5)比 Redim 數(shù)組使其更大好得多。您可能浪費一些內(nèi)存(如果您沒有使用所有的元素),但獲得的好處是速度變得更快。

技巧 14:使用響應緩沖
您可以通過啟用“響應緩沖”,將要輸出的一整頁緩沖起來。這樣就將寫到瀏覽器的量減到最少,從而改善總體性能。每個寫操作都會產(chǎn)生很大的系統(tǒng)開銷(在 IIS 中以及在通過網(wǎng)絡發(fā)送的數(shù)據(jù)量方面),因此寫操作越少越好。由于其啟動慢且使用 Nagling 算法(用來減輕網(wǎng)絡塞車情況),TCP/IP 在發(fā)送一些大的數(shù)據(jù)塊時比必須發(fā)送許多小的數(shù)據(jù)塊時的效率高得多。

有兩個方法啟用響應緩沖。第一種,您可以使用 Internet Services Manager 為整個應用程序啟用響應緩沖。我們建議采用這種方法,在 IIS 4.0 和 IIS 5.0 中默認為新的 ASP 應用程序啟用響應緩沖。第二種,可以在每個 ASP 頁面的接近頂端的地方加入下面的代碼行,從而啟用響應緩沖:

<% Response.Buffer = True %>


此代碼行必須在任何響應數(shù)據(jù)被寫到瀏覽器之前執(zhí)行(即,在任何 HTML 出現(xiàn)在 ASP 腳本之前以及在使用 Response.Cookies 集合設(shè)置任何 Cookies 之前)。一般來說,最好為整個應用程序啟用響應緩沖。這樣,您就不必在每個頁面最上面寫入上述的代碼行。

Response.Flush
關(guān)于響應緩沖有一個常見的抱怨,就是用戶感覺到 ASP 頁面的響應速度很慢(即使整個響應時間得到改進),因為他們必須等到整個頁面生成,然后他們才能看到東西。對于運行時間長的頁面,您可以設(shè)置 Response.Buffer = False,禁用響應緩沖。但是,一個更好的策略是利用 Response.Flush 方法。這種方法將 ASP 轉(zhuǎn)換的所有 HTML 送到瀏覽器。例如,在轉(zhuǎn)換 1,000 行的表的前 100 行之后,ASP 可以調(diào)用 Response.Flush,強制將轉(zhuǎn)換的結(jié)果送到瀏覽器,這樣可使用戶在其余的行準備好之前看到頭 100 行。這種技術(shù)可以將響應緩沖與瀏覽器逐漸顯示數(shù)據(jù)完美地結(jié)合在一起。

(注意在上面的 1,000 行表的舉例中,許多瀏覽器在它們看到關(guān)閉 </table> 標記之前不會開始顯示表。檢查您的目標瀏覽器是否支持。為避免這種情況,將表分成多個具有較少行的表,并在每個表之后調(diào)用 Response.Flush。較新版本的 Internet Explorer 在表完全下載之前就開始顯示表,如果您指定表列寬,顯示速度就會特別快,這樣做可避免強制 Internet Explorer 通過測量每個單元格的內(nèi)容寬度來計算列寬。)

另一個關(guān)于響應緩沖的常見的抱怨是,當產(chǎn)生非常大的頁面時,將占用許多服務器內(nèi)存。撇開產(chǎn)生大頁面的方法不談,這種問題也可通過巧妙使用 Response.Flush 來加以解決。