引言 性能是一個特征
您必須預先設計性能
否則您以後就得重寫應用程序
就是說
有哪些好的策略可使 Active Server Pages (ASP) 應用程序性能達到最佳?
本文介紹了優化 ASP 應用程序和 Visual Basic® Scripting Edition (VBScript) 的技巧
本文討論了許多陷阱
本文列出的建議已經在 和其它站點中進行了測試
效果十分顯著
本文假定您已經對 ASP 開發
包括 VBScript 和/或 JScript
ASP Application
ASP Session 和其它 ASP 固有對象(Request
Response 和 Server)有了基本了解
通常
ASP 性能主要取決於 ASP 代碼本身以外的很多因素
我們不在一篇文章中羅列出所有的信息
在本文結尾處我們列出了與性能有關的資源
這些鏈接涵蓋了 ASP 和非 ASP 主題
包括 ActiveX® 數據對象 (ADO)
組件對象模型 (COM)
數據庫和 Internet Information Server (IIS) 配置
這些都是我們喜歡的一些鏈接
一定要去看看
技巧 將經常使用的數據緩存在 Web 服務器上 典型的 ASP 頁從後端數據存儲中檢索數據
然後將結果轉換成超文本標記語言 (HTML)
無論數據庫的速度如何
從內存中檢索數據總要比從後端數據存儲中檢索數據快得多
從本地硬盤讀取數據通常也比從數據庫中檢索數據更快
因此
通常可以將數據緩存在 Web 服務器上(存儲在內存或磁盤中)
來提高性能
緩存是傳統的以空間換取時間的做法
如果您緩存的內容正確
那麼您可以看到性能會有顯著的提高
為使緩存有效
必須保存那些經常重復使用的數據
且要重新計算這些數據需要(適度)大的開銷
如果緩存的都是些陳舊的數據
就會造成內存浪費
不經常發生改變的數據是很好的緩存候選數據
因為您不必擔心隨著時間的遷移該數據與數據庫同步的問題
組合框列表
引用表
DHTML 碎片
擴展標記語言 (XML) 字符串
菜單項和站點配置變量(包括數據源名稱 (DSN)
Internet 協議 (IP) 地址和 Web 路徑)都是很好的緩存候選內容
注意您可以緩存數據的
表示
而不緩存數據本身
如果 ASP 頁很少更改
且緩存的開銷也很大(例如
整個產品目錄)
則應考慮事先產生 HTML
而不是在響應每個請求時重新顯示
應將數據緩存在哪裡
有哪些緩存策略?通常
數據緩存在 Web 服務器的內存或磁盤中
下兩個技巧講述了這兩個方法
技巧 : 將經常使用的數據緩存在 Application 或 Session 對象中 ASP Application 和 Session 對象為將數據緩存在內存中提供了方便的容器
您可以將數據指派到 Application 和 Session 對象中
這些數據在 HTTP 調用之間保留在內存中
Session 數據是按每個用戶分別存儲的
而 Application 數據則在所有用戶之間共享
什麼時候將數據裝載到 Application 或 Session 中呢?通常
數據是在啟動 Application 或 Session 時裝載
要在 Application 或 Session 啟動過程中裝載數據
應將適當的代碼分別添加到 Application_OnStart() 或 Session_OnStart() 中
這些函數應在 Global
asa 中
如果沒有
則可以添加這些函數
還可以在第一次需要時裝載該數據
為此
在 ASP 頁中添加一些代碼(或編寫一個可重復使用的腳本函數)
以檢查數據是否存在
如果不存在
就裝載數據
這是一個傳統的性能技術
稱為
惰性計算
在您知道需要某一個值以前不計算該值
例如
<%
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 記錄集持久函數 GetRows()
GetString() 或 Save()(ADO
)
可加快速度且更容易一些
其詳細情況已超出本文所討論的范圍
但下面給出了一個函數舉例
說明使用 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
在適當的條件下
可以將 ADO 記錄集本身緩存在 Application 或 Session 作用域中
有兩個警告
必須將 ADO 標記為自由線程
必須使用斷開連接的記錄集
如果不能保證滿足這兩個要求
則不要緩存 ADO 記錄集
在下面的
非敏捷組件
和
不要緩存連接
技巧中
我們將討論將 COM 對象存儲在 Application 或 Session 作用域中的危險性
當您將數據存儲在 Application 或 Session 作用域時
數據將保留在那裡
直到您以編程方式改變它
Session 過期或 Web 應用程序重新啟動為止
如果數據需要更新怎麼辦?要手工強制對 Application 數據進行更新
您可以訪問只有管理員才可訪問的 ASP 頁來更新數據
或者
您可以通過函數定期自動刷新數據
下面例子存儲帶有緩存數據的時間戳
並隔一段時間後刷新數據
<%
error handing not shown
Const UPDATE_INTERVAL =
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?) = Events
Application(?LastUpdate?) = CStr(Now)
Application
Unlock
End If
End Sub
請參見 World
s Fastest ListBox with Application Data
上面還有一個例子
要知道在 Session 或 Application 對象中緩存大的數組不是一個好的做法
在訪問數組的任何元素之前
腳本語言的語法要求必須臨時復制整個數組
例如
如果將由字符串組成的有
個元素的數組(該數組將美國郵政編碼映射到當地的氣象站)緩存在 Application 對象中
ASP 必須先將所有的
個氣象站復制到臨時數組中
然後才能提取一個字符串
在這種情況下
用自定義方法建立一個自定義組件來存儲氣象站
或使用一個詞典組件會更好
再警告大家一下
不要將嬰兒與洗澡水一起倒掉
數組能快速查尋和存儲在內存中是鄰近的關鍵數據對
索引一個詞典比索引一個數組要慢得多
應針對您的實際情況
選擇提供最佳性能的數據結構
技巧 將數據和 HTML 緩存在 Web 服務器的磁盤上 有時
數據可能太多
無法都緩存在內存中
太多
只是一個說法
這要看您想消耗多少內存
以及需緩存的項目數和檢索這些項目的頻率
在任何情況下
如果數據太多而無法都緩存在內存中
則考慮
From:http://tw.wingwit.com/Article/program/net/201311/12287.html