如何增強ASP程序性能(2) 2000-08-11· 編譯:甘冀平·Yesky
技巧6:聰明地使用Session對象
Session在繁忙站點上使用時有幾個缺陷。繁忙的意思是:站點上每秒有上百的頁面被請求,或者同時有上千的訪問用戶。這個技巧對于那些要求水平擴(kuò)展強的站點非常重要,也就是指這些站點:它們利用多個服務(wù)器完成數(shù)據(jù)裝載或者處理大量容錯。對于小型站點,比如內(nèi)部網(wǎng)Intranet,Session是非常值得提倡的。
再次重申,ASP自動地為每一個首次點擊Web服務(wù)器的用戶創(chuàng)建一個Session,每一個Session占有大約10KB的內(nèi)存,生存期默認(rèn)是20分鐘。
使用Session最大的問題不是性能,而是擴(kuò)展性,Session不能跨越多個Web服務(wù)器,一旦在一個服務(wù)器上創(chuàng)建了Session,它的數(shù)據(jù)就駐留在那里。這意味著,如果在Web上使用Session,你就得為每一個直接訪問存放Session服務(wù)器的用戶請求設(shè)計一個策略。這就是將用戶“粘”在Web服務(wù)器上,術(shù)語“sticky sessions”就來源于此。如果Web服務(wù)器遇到障礙,“Stuck”用戶就會丟失他們的Session狀態(tài),因為Session不保留在磁盤上。
執(zhí)行粘性session的策略包括硬件與軟件解決方式,比如windows2000高級服務(wù)器中的 Network Load Balancing 以及Cisco公司的Local Director,但換取這些要犧牲一定的擴(kuò)展性。
Application對象也不能跨越服務(wù)器。如果需要在Web群中共享并更新Application數(shù)據(jù),就需要使用后臺數(shù)據(jù)庫。然而,只讀Application數(shù)據(jù)在Web群中仍然很有用。
許多對任務(wù)要求嚴(yán)格的站點都要設(shè)立至少2個Web服務(wù)器,所以在設(shè)計嚴(yán)格任務(wù)的應(yīng)用程序時,就需要執(zhí)行“sticky sessions”,或者簡單地避免使用Session,同時也可以采取其他保存用戶狀態(tài)到獨立Web服務(wù)器的管理技術(shù)。
如果不使用Session,一定要確認(rèn)將它們關(guān)閉,這可以通過Internet服務(wù)管理器實現(xiàn)。如果決定使用Session,可以通過幾種方法來最小化它們的影響。
可以將不需要Session的內(nèi)容(比如幫助畫面,訪問者區(qū)域,等等)移動到關(guān)閉Session的獨立ASP應(yīng)用程序中。在基礎(chǔ)頁面上,可以給ASP一個指示,讓它不需要使用Session。將下面的代碼直接加入到ASP頁面的頭部:
<% @EnableSessionState=False %>
使用這個指示的一個很好的解釋是在框架結(jié)構(gòu)中Session創(chuàng)建了一個有趣的問題。ASP確保在一個時刻只有一個來自Session的請求被執(zhí)行,這就確保了如果瀏覽器為單個用戶請求多個頁面時,只有一個ASP請求在那時能夠接受Session,如此就避免了存取Session對象時的多線程問題。很不幸,在框架結(jié)構(gòu)中的所有頁面將按照連續(xù)的順序顯示出來,一個接一個,而不是同時,所以用戶為了看到整個框架必須要等很長時間。規(guī)則是:如果一定的框架頁面沒有使用Session,就一定要告訴ASP直接使用@EnableSessionState=False。
除了使用Session對象,還有許多其他管理會話狀態(tài)的選擇。對于小數(shù)量的狀態(tài)(小于4KB),我們通常建議使用cookie、查詢字符串變量以及表單隱藏域。對于象購物車一樣的大數(shù)量數(shù)據(jù),后臺數(shù)據(jù)庫是最合適的選擇。
技巧7:將代碼裝入COM對象中
如果要編寫很多VBScript或者JScript,為了提個性能,可以將代碼編寫成COM對象并且編譯使用。編譯代碼基本上比解釋性代碼運行快許多,編譯組件對象可通過“early binding”存取其他COM對象,這比在腳本中調(diào)用組件要有效。
這么做有許多優(yōu)點:
COM對象有益于從商業(yè)規(guī)則中獨立出表達(dá)式規(guī)則 COM對象使代碼重用變?yōu)榭赡? 許多開發(fā)者發(fā)現(xiàn)用VB,C++或者Visual J++編寫程序,比ASP更容易調(diào)試 COM對象也有缺點,包括初始開發(fā)時間和對不同編程技巧的需要。注意將少量ASP代碼做成COM對象組件不會有好處,反而可能導(dǎo)致性能的損失,從而失去了編譯代碼的優(yōu)勢。怎樣組合使用ASP腳本和COM對象達(dá)到最佳性能是一個測試的問題。我們注意到微軟公司已經(jīng)大規(guī)模在Windows 2000/IIS 5.0上提高了腳本與ADO的性能,由此,隨著IIS5.0版本的引進(jìn),減少了編譯代碼的性能優(yōu)勢。
技巧8:使用Option Explicit
要在ASP文件中使用Option Explicit定義,并且放置到ASP文件的頭部,從而強迫開發(fā)者在使用前聲明所有的變量。許多程序員都認(rèn)為這在應(yīng)用程序調(diào)試時非常有用,因為它避免了產(chǎn)生錯誤類型變量以及偶然創(chuàng)建新變量的可能。
也許更重要的是,聲明的變量要大大快于非聲明變量。
技巧9:拷貝經(jīng)常使用的數(shù)據(jù)到腳本變量中
在ASP中存取COM對象時,應(yīng)該拷貝經(jīng)常使用的對象數(shù)據(jù)到腳本變量中,這樣就減少了對COM對象的方法調(diào)用。這些調(diào)用要比存取腳本變量相對來說費時費力。當(dāng)存取Collection和Dictionary對象時,使用這項技巧也減少了昂貴的查找操作。
通常,如果要不止一次地存取對象數(shù)據(jù),就應(yīng)將數(shù)據(jù)放入腳本變量中,對象數(shù)據(jù)主要也就是Request變量(表單和查詢字符串變量)。比如,站點要傳遞一個叫做UserID的查詢字符串變量,假設(shè)它將在一個特殊頁面被引用12次,那么不需要調(diào)用Request(“UserID”)12次,只要在ASP頁面的頭部分配給UserID一個變量,然后在頁面中使用它,這樣做就節(jié)省了11次COM方法的調(diào)用。
實際中,存取COM屬性或方法是很昂貴的,下面的例子展示了通用代碼:
Foo.bar.blah.baz = Foo.bar.blah.qaz(1) If Foo.bar.blah.zaq = Foo.bar.blah.abc Then ' ...
上面的代碼執(zhí)行后,發(fā)生以下事情:
1、變量Foo被當(dāng)作全局對象 2、變量bar被當(dāng)作Foo的一員 3、變量blah被當(dāng)作Foo.bar的一員 4、變量qaz被當(dāng)作Foo.bar.blah的一員 5、調(diào)用Foo.bar.blah.quaz(1) 6、再執(zhí)行步驟1到3分解baz 7、分解baz做為Foo.bar.blah的一員 8、再執(zhí)行步驟1到3分解zaq 9、再執(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
注意:這個技巧也可以應(yīng)用在VB編程中。
技巧10:避免再定義數(shù)組
爭取不要再定義數(shù)組。考慮到性能問題,如果機器的物理內(nèi)存大小不夠,最好按最差情況或者最佳情況設(shè)置數(shù)組的初始尺寸,需要時再重新定義。
下面的代碼展示了Dim和Redim的使用:
< % 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ù)組初始尺寸為合適的大小是非常好的,而不要用Redim加大數(shù)組。這么做也許浪費了一些內(nèi)存(如果沒有完全地使用空間),但是贏得了速度。
|