如何增強ASP程式效能

來源:互聯網
上載者:User
程式|效能


  效能是一個很重要的特徵。你需要事先設計好效能指標,否則日後就要為此重新編寫程式。就是說:要設想好怎樣最佳化地執行ASP程式?

   本文提出了一些最佳化ASP應用和VBScript的技巧,許多技巧和缺陷都經過了研討。這裡列出的建議已經在http://www.microsoft.com 和其他網站上進行了測試,都工作得非常好。本文假設你具備ASP開發的基本知識,包括VBScript或者JScript,ASP應用程式,ASP Session,以及其他ASP內建對象(Request,Response和Server)。

   通常,ASP的執行效能遠遠不僅僅依賴ASP代碼本身!在本文的尾部列出了與效能相關的資源,它們含概了ASP和非ASP的部分,包含ActiveX Data Objects(ADO),Component Object Model(COM),資料庫(Database),以及Internet資訊服務器(IIS)的配置。除了這些,還有一些非常好的連結值得你一看。

技巧1:在Web伺服器上緩衝經常使用的資料

   典型的情況是:ASP頁面從後台儲存中取回資料,然後以超文字標記語言 (HTML)(HTML)的形式形成結果。不管資料庫的速度如何,從記憶體中取回資料要比從後台存放裝置中快得多。從本地硬碟讀取資料通常也非常快。所以,提高效能可以通過快取服務器上的資料來實現,無論是將資料緩衝在記憶體中,或者本地硬碟中。

   緩衝是經典的“空間換時間”的折中方式。如果緩衝得恰當,就可以看到顯著的效能提升。為了讓緩衝有效,必須保證快取資料是經常要重用的,而且也是計算起來繁瑣的。裝滿陳舊資料的緩衝是對記憶體的浪費。

   不經常改變的資料是緩衝的較好對象,因為不需要隨時考慮這些資料更新後的同步操作。組合框、參考表格、DHTML代碼、擴充標記語言串、菜單以及網站組態變數(包括資料來源名字DSNS,Internet協議地址IP以及Web路徑)都是很好的緩衝對象。注意:要快取資料運算式而不是資料本身。如果一個ASP頁面經常變化並且很費力去緩衝(比如整個產品目錄),就要考慮預產生HTML,而不是每次發生請求時再描述它。

技巧2:在Application或Session對象中緩衝經常使用的資料

   ASP中的Application和Session對象是在記憶體中快取資料的便利容器。你可以將資料賦值給Application和Session對象,這些資料在HTTP調用期間將一直保持在記憶體中。Session中的資料是? 一個使用者服務的,Application中的資料是所有使用者共用的。

   何時需要在Application和Session中裝入資料?通常,當應用程式啟動或者會話開始時,資料就被裝入了。為了在這時裝入資料,在Application OnStart()或者Session OnStart()中分別添加適當的代碼。這些函數位於檔案Global.asa中,如果原來不存在,就添加上。也可以在資料首次需要的時候調入,在ASP頁面中添加代碼,檢查資料是否存在,如果沒有發現,就調入它。這裡有一個例子,它代表了被稱為“lazy evalution”的經典效能處理技術:直到需要時,再去計算。例子如下:

$#@60;%Function GetEmploymentStatusList Dim d d = Application("EmploymentStatusList") If d = "" Then  FetchEmploymentStatusList function (not shown)  fetches data from DB, returns an Array d = FetchEmploymentStatusList() Application("EmploymentStatusList") = d End If GetEmploymentStatusList = dEnd Function%$#@62;
對於不同的資料,可以編寫類似的函數代碼。

   資料應該按什麼格式儲存?任何變數類型都可以,因為所有的指令碼變數都是不同的。比如說,可以儲存為字串、整型或者資料。通常,將ADO記錄集的內容儲存到這些變數類型中一個。為了從ADO記錄集中取出資料,需要手工地拷貝資料到VBScript變數中,每次一個欄位。使用任意一個ADO記錄集的函數functions GetRows(),GetString() 或者 Save() (ADO 2.5)都非常得快速而且簡單,這裡有個函數,描述了如何使用GetRows()返回記錄集資料的數組:
 Get Recordset, return as an ArrayFunction FetchEmploymentStatusList Dim rs  Set rs = CreateObject("ADODB.Recordset") rs.Open "select StatusName, StatusID from EmployeeStatus", _ "dsn=employees;uid=sa;pwd=;" FetchEmploymentStatusList = rs.GetRows() " Return data as an Array rs.Close Set rs = NothingEnd Function
上述代碼的一個更深的技巧是為列表緩衝了HTML。下面是個簡單的例子:
 Get Recordset, return as HTML Option listFunction FetchEmploymentStatusList Dim rs, fldName, s Set rs = CreateObject("ADODB.Recordset") rs.Open "select StatusName, StatusID from EmployeeStatus", _ "dsn=employees;uid=sa;pwd=;" s = "$#@60;select name=""EmploymentStatus"$#@62;" & vbCrLf Set fldName = rs.Fields("StatusName")  ADO Field Binding Do Until rs.EOF  Next line violates Dont Do String Concats,  but its OK because we are building a cache s = s & " $#@60;option$#@62;" & fldName & "$#@60;/option$#@62;" & vbCrLf rs.MoveNext Loop s = s & "$#@60;/select$#@62;" & vbCrLf rs.Close Set rs = Nothing  See Release Early FetchEmploymentStatusList = s  Return data as a StringEnd Function
在合適的環境下,可以在Application或者Session中緩衝ADO記錄集本身,但是有2點提示:
  • ADO必須是自由線程標記的
  • 需要使用disconnected recordset方式
   如果不能保證上述2個條件,就不要緩衝ADO記錄集,因為這會產生很大的危險性。

   當在Application或Session中儲存資料後,資料將一直保持,除非程式改變它、Session變數到期或者Web應用程式重新啟動。如果資料需要更新,怎麼辦?可以調用只有管理員才能訪問的ASP頁面來更新資料,或者,通過函數周期性的自動更新資料。下面的例子中,與快取資料一起儲存了時鐘標記,過一段時間後,就重新整理資料。
$#@60;% error handing not shown...Const UPDATE_INTERVAL = 300  Refresh interval, in seconds Function to return the employment status listFunction GetEmploymentStatusList UpdateEmploymentStatus GetEmploymentStatusList = Application("EmploymentStatusList")End Function Periodically update the cached dataSub UpdateEmploymentStatusList Dim d, strLastUpdate strLastUpdate = Application("LastUpdate") If (strLastUpdate = "") Or _ (UPDATE_INTERVAL $#@60; DateDiff("s", strLastUpdate, Now)) Then  Note: two or more calls might get in here. This is okay and will simply  result in a few unnecessary fetches (there is a workaround for this)  FetchEmploymentStatusList function (not shown)  fetches data from DB, returns an Array d = FetchEmploymentStatusList()  Update the Application object. Use Application.Lock()  to ensure consistent data Application.Lock Application("EmploymentStatusList") = d Application("LastUpdate") = CStr(Now) Application.Unlock End IfEnd Sub
有另外一個例子,請參閱 World’s Fastest ListBox with Application Data。

   必須意識到,在Session或者Application對象中緩衝大容量的數組不是一個好的方法。存取數組中任何元素前,指令碼語言的規則要求首先要建立整個數組的臨機操作備份。比如,如果在Application對象中緩衝一個100,000個元素的數組,其中包含U.S.郵遞區號與本地氣象站的對應關係,ASP就必須首先拷貝所有100,000個氣象站資訊到臨時數組中,然後才能選擇其中一個字串進行處理。在這種情況下,建立一個定製的組件,編寫一個方法儲存氣象站資訊,是非常好的方法。

技巧3:在Web伺服器磁碟上快取資料和HTML頁面

   有時候,有“許多”資料要在記憶體中緩衝。“許多”是相對而言的,它取決於能消耗多少記憶體、快取項目的數量以及取回資料的頻度。任何情況下,如果需要在記憶體中緩衝大量的資料,請考慮以text或者XML檔案格式在Web伺服器硬碟上做緩衝。當然,也可以混合使用硬碟快取資料以及記憶體快取資料,從而達到最佳緩衝。

   注意:當測試一個單一ASP頁面的效能時,從磁碟取回資料不一定比從網路資料庫中取回資料快,但是緩衝減少了網路資料庫的調用。在大規模調用時,這將明顯地提高網路的吞吐能力。緩衝一個費時的查詢結果是非常有用的,比如對於一個複雜的預存程序,或者大量的結果資料。

   ASP和COM提供了幾種建立基於磁碟緩衝配置的工具。ADO記錄集的Save()和 Open()函數負責儲存和調入磁碟上的記錄集。另外還有一些組件:
  • Scripting.FileSystemObject 允許你建立、讀取和寫檔案
  • MSXML,Microsoft XML 解析器隨Internet Explorer而來,支援儲存和裝入XML文檔
  • LookupTable對象(比如在MSN上使用)是從磁碟調入簡單列表的很好選擇。
   最後,考慮緩衝磁碟資料的運算式,而不是資料本身。預先處理的HTML可以儲存為.htm或者.asp檔案,連結直接指向它們。使用諸如XBuilder或者Microsoft SQL Server Internet發布類的商業工具,能夠自動處理這些過程。而且,也可以在.asp檔案中包含HTML程式片斷。同樣,也可使用FileSystemObject從磁碟上讀取HTML檔案,或者使用XML for early rendering來做這個工作。

技巧4:避免在Application或Session對象中緩衝非輕快型組件

   在Application或Session對象中快取資料是一個很好的方法,但是,緩衝COM對象卻有嚴重的缺陷。在Application或Session對象中緩衝經常使用的COM對象這個工作是非常迷人的,但是很不幸,許多COM對象,包括用Visual Basic 6.0或者以前版本編寫的對象組件,當儲存在Application或Session對象中後,都會產生嚴重的瓶頸問題。

   特別地,當組件編寫得不是很輕巧時,就極可能產生瓶頸問題。一個輕型組件就是標記了ThreadingModel=Both的組件,其中合計了自由線程的排列(FTM),或者標記了ThreadingModel=Neutral(Neutral模式是Windows2000和COM+中的新特徵)。下面的組件不是輕型的:
  • Free-threaded組件(除非被集合成FTM)
  • Apartment-threaded組件
  • Single-threaded組件
   Configured components不是輕型組件,除非它們是Neutral-threaded的。Apartment-threaded組件和其他非輕型組件在頁範圍內工作得很好,就是說,它們是在一個單一ASP頁面中建立並釋放的。

   如果緩衝了非輕型組件,將會發生什麼錯誤?在Session對象中緩衝的非輕型組件將會“鎖住”會話。ASP維護著一個響應請求的背景工作執行緒池,通常,新的請求被第一個可用的背景工作執行緒控制。如果一個會話被鎖在一個線程中,那麼請求就被迫等待到相關的線程變為可用。這裡有一個類比:你前往一個超級市場,挑選了一些食品,並在3號付款台付款。從那以後,只要在那個超級市場買食品付款,你就會經常到3號付款台去,雖然其他的付款台人少些甚至沒有人。

技巧5:不要在Application或Session對象中快取資料庫串連

   緩衝ADO串連通常不是一個好的策略。如果一個連線物件被儲存在Application對象中,並在所有的頁面使用,那麼所有頁面將會爭奪該串連的使用。如果儲存在ASP Session對象中,那麼將要為每一個使用者都開啟資料庫連接。這將挫敗串連池的使用意圖,並且在Web伺服器和資料庫上都施加了不必要的高代價壓力。

   為了替代快取資料庫串連,可以在使用ADO的每個ASP頁面中建立並釋放ADO對象。這將非常有效,因為IIS擁有內建的資料庫連接池。更準確地說,IIS自動處理OLEDB和ODBC串連池,這將保證在每個頁面建立並且釋放串連的工作高效進行。

   由於串連的記錄集儲存了資料庫連接的參考,所以,不要在Application或Session對象中緩衝串連的記錄集。然而,可以安全地緩衝disconnected類型的記錄集,它們並不儲存相應資料庫連接的參考。為了斷開記錄集,執行下面2步:
 Set rs = Server.CreateObject("ADODB.RecordSet") rs.CursorLocation = adUseClient  step 1  Populate the recordset with data rs.Open strQuery, strProv  Now disconnect the recordset from the data provider and data source rs.ActiveConnection = Nothing  step 2
   更多的關於串連池的資訊請訪問 ADO and SQL Server。


相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。