- Login
帳號:
密碼:
ASP MENU
線上教學
   ASP 教學
VB.NET 教學
JSP 教學
JAVA 教學
完整 ASP 教學
程式下載
   ASP 程式下載
提供 ASP 程式
程式量身訂做
   收費標準
填寫需求表
討論交流專區
   程式討論區
電腦資訊交流
工作機會
   社會人就職情報
汎亞人力銀行
大台中人力銀行
大高雄人力銀行
相關連結
   ASP 虛擬空間
ASP 相關網站
聯絡我們
   意見信箱
加入會員程式討論區線上購物回首頁
ASP 教學
如何增強ASP程序性能(1)
簡介

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

  本文提出了一些優化ASP應用和VBScript的技巧,許多技巧和缺陷都經過了研討。這埵C出的建議已經在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)的形式形成結果。不管數據庫的速度如何,從內存中取回數據要比從後台存儲設備中快得多。從本地硬盤讀取數據通常也非常快。所以,提高性能可以通過緩存服務器上的數據來實現,無論是將數據緩存在內存中,或者本地硬盤中。

  緩存是經典的“空間換時間”的折中方式。如果緩存得恰當,就可以看到顯??的性能提昇。為了讓緩存有效,必須保證緩存數據是經常要重用的,而且也是計算起來繁瑣的。裝滿陳舊數據的緩存是對內存的浪費。

  不經常改變的數據是緩存的較好對象,因為不需要隨時考慮這些數據更新後的同步操作。組合框、參考表格、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”的經典性能處理技術:直到需要時,再去計算。例子如下:

<%
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 = d
End Function
%>

對於不同的數據,可以編寫類似的函數代碼。

  數據應該按什麼格式保存?任何變量類型都可以,因為所有的腳本變量都是不同的。比如說,可以保存為字符串、整型或者數據。通常,將ADO記錄集的內容存儲到這些變量類型中一個。為了從ADO記錄集中取出數據,需要手工地拷貝數據到VBScript變量中,每次一個字段。使用任意一個ADO記錄集的函數functions GetRows(),GetString() 或者 Save() (ADO 2.5)都非常得快速而且簡單,這埵陪茖蝻ヾA描述了如何使用GetRows()返回記錄集數據的數組:

' Get Recordset, return as an Array
Function 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 = Nothing
End Function

上述代碼的一個更深的技巧是為列表緩存了HTML。下面是個簡單的例子:

' Get Recordset, return as HTML Option list
Function FetchEmploymentStatusList
Dim rs, fldName, s
Set rs = CreateObject("ADODB.Recordset")
rs.Open "select StatusName, StatusID from EmployeeStatus", _
"dsn=employees;uid=sa;pwd=;"
s = "<select name=""EmploymentStatus">" & vbCrLf
Set fldName = rs.Fields("StatusName") ' ADO Field Binding
Do Until rs.EOF
' Next line violates Don't Do String Concats,
' but it's OK because we are building a cache
s = s & " <option>" & fldName & "</option>" & vbCrLf
rs.MoveNext
Loop
s = s & "</select>" & vbCrLf
rs.Close
Set rs = Nothing ' See Release Early
FetchEmploymentStatusList = s ' Return data as a String
End Function

在合適的環境下,可以在Application或者Session中緩存ADO記錄集本身,但是有2點提示:

ADO必須是自由線程標記的
需要使用disconnected recordset方式
  如果不能保證上述2個條件,就不要緩存ADO記錄集,因為這會產生很大的危險性。

  當在Application或Session中保存數據後,數據將一直保持,除非程序改變它、Session變量到期或者Web應用程序重新啟動。如果數據需要更新,怎麼辦?可以調用只有管理員才能訪問的ASP頁面來更新數據,或者,通過函數周期性的自動更新數據。下面的例子中,與緩存數據一起保存了時鐘標記,過一段時間後,就刷新數據。

<%
' error handing not shown...
Const UPDATE_INTERVAL = 300 ' Refresh interval, in seconds

' Function to return the employment status list
Function GetEmploymentStatusList
UpdateEmploymentStatus
GetEmploymentStatusList = Application("EmploymentStatusList")
End Function

' Periodically update the cached data
Sub UpdateEmploymentStatusList
Dim d, strLastUpdate
strLastUpdate = Application("LastUpdate")
If (strLastUpdate = "") Or _
(UPDATE_INTERVAL < 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 If
End 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




頂端
本網頁最佳瀏覽模式為:瀏覽器 IE4.0 以上    解析度: 800 x 600
Copyright © 2000-2020 COOLASP All Rights Reserved