改進ASP程式中的字串處理效能

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

簡介
  
  編寫 ASP 頁面時,開發人員實際上是建立一個格式化的文字資料流,通過 ASP 提供的 Response 對象寫入 網頁用戶端。建立此文字資料流的方法有多種,而您選擇的方法將對 Web 應用程式的效能和可縮放性產生很大影響。很多次,在我協助客戶最佳化其 Web 應用程式的效能時,發現其中一個比較有效方法是更改 HTML 流的建立方式。本文將介紹幾種常用技術,並測試它們對一個簡單的 ASP 頁面的效能所產生的影響。
  
  ASP 設計
  
  許多 ASP 開發人員都遵循良好的軟體工程原則,儘可能地將其代碼模組化。這種設計通常使用一些包含檔案,這些檔案中包含對頁面的特定不連續部分進行格式化產生的函數。這些函數的字串輸出(通常是 HTML 表格代碼)可以通過各種組合建立一個完整的頁面。某些開發人員對此方法進行了改進,將這些 HTML 函數移到 Visual Basic COM 組件中,希望充分利用已編譯的代碼提供的額外效能。
  
  儘管這種設計方法很不錯,但建立組成這些不連續 HTML 程式碼組件的字串所使用的方法將對 Web 網站的效能和可縮放性產生很大的影響,無論實際的操作是在 ASP 包含檔案中執行還是在 Visual Basic COM 組件中執行。
  
  字串串連
  
  請看以下 WriteHTML 函數的代碼片斷。名為 Data 的參數只是一個字串數組,其中包含一些要格式化為表格結構的資料(例如,從資料庫返回的資料)。
  
  Function WriteHTML( Data )
  Dim nRep
  For nRep = 0 to 99
  sHTML = sHTML & vbcrlf _
  & "<TR><TD>" & (nRep + 1) & "</TD><TD>" _
  & Data( 0, nRep ) & "</TD><TD>" _
  & Data( 1, nRep ) & "</TD><TD>" _
  & Data( 2, nRep ) & "</TD><TD>" _
  & Data( 3, nRep ) & "</TD><TD>" _
  & Data( 4, nRep ) & "</TD><TD>" _
  & Data( 5, nRep ) & "</TD></TR>"
  Next
  WriteHTML = sHTML
  End Function
  
  這是很多 ASP 和 Visual Basic 開發人員建立 HTML 程式碼時常用的方法。sHTML 變數中包含的文本返回到調用代碼,然後使用 Response.Write 寫入用戶端。當然,這還可以表示為直接嵌入不包含 WriteHTML 函數的頁面的類似代碼。此代碼的問題是,ASP 和 Visual Basic 使用的字串資料型別(BSTR 或 Basic 字串)實際上無法更改長度。這意味著每當字串長度更改時,記憶體中字串的原始表示形式都將遭到破壞,而且將建立一個包含新字串資料的新的表示形式:這將增加分配記憶體和解除配置記憶體的操作。當然,ASP 和 Visual Basic 已為您解決了這一問題,因此實際開銷不會立即顯現出來。分配記憶體和解除配置記憶體要求基本運行時代碼解除各個專用鎖定,因此需要大量開銷。當字串變得很大並且有大塊記憶體要被快速連續地分配和解除配置時,此問題變得尤為明顯,就像在大型字串串連期間出現的情況一樣。儘管這一問題對單使用者環境的影響不大,但在伺服器環境(例如,在 Web 服務器上啟動並執行 ASP 應用程式)中,它將導致嚴重的效能和可縮放性問題。
  
  下面,我們回到上述程式碼片段:此代碼中要執行多少個字串分配操作?答案是 16 個。在這種情況下,“&”運算子的每次應用都將導致變數 sHTML 所指的字串被破壞和重新建立。前面已經提到,字串分配的開銷很大,並且隨著字串的增大而增加,因此,我們可以對上述代碼進行改進。
  
  快捷的解決方案
  
  有兩種方法可以緩解字串串連的影響,第一種方法是嘗試減小要處理的字串的大小,第二種方法是嘗試減少執行字串分配操作的數目。請參見下面所示的 WriteHTML 程式碼的修訂版本。
  
  Function WriteHTML( Data )
  
  Dim nRep
  
  For nRep = 0 to 99
  sHTML = sHTML & ( vbcrlf _
  & "<TR><TD>" & (nRep + 1) & "</TD><TD>" _
  & Data( 0, nRep ) & "</TD><TD>" _
  & Data( 1, nRep ) & "</TD><TD>" _
  & Data( 2, nRep ) & "</TD><TD>" _
  & Data( 3, nRep ) & "</TD><TD>" _
  & Data( 4, nRep ) & "</TD><TD>" _
  & Data( 5, nRep ) & "</TD></TR>" )
  Next
  
  WriteHTML = sHTML
  
  End Function
  
  乍一看,可能很難發現這段代碼與上一個程式碼範例的差別。其實,此代碼只是在 sHTML = sHTML & 後的內容外面加上了括弧。這實際上是通過更改優先順序,來減小大多數字串串連操作中處理的字串大小。在最初的程式碼範例中,ASP 編譯器將查看等號右邊的運算式,並從左至右進行計算。結果,每次重複都要進行 16 個串連操作,這些操作針對不斷增長的 sHTML 進行。在新版本中,我們提示編譯器更改操作順序。現在,它將按從左至右、從括弧內到括弧外的順序計算運算式。此技術使得每次重複包括 15 個串連操作,這些操作針對的是不會增長的較小字串,只有一個是針對不斷增長的大的 sHTML。圖 1 顯示了這種最佳化方法與標準串連方法在記憶體使用量模式方面的比較。
  

 


  

圖 1:標準串連與加括弧串連在記憶體使用量模式方面的比較


  
  在特定情況下,使用括弧可以對效能和可縮放性產生十分顯著的影響,後文將對此進行進一步的說明。
  
  StringBuilder
  
  我們已經找到瞭解決字串串連問題的快捷方法,在多數情況下,此方法可以達到效能和投入的最佳平衡。但是,如果要進一步提高構建大型字串的效能,需要採用第二種方法,即減少字串分配操作的數目。為此,需要使用 StringBuilder。StringBuilder 是一個類,用於維護可配置的字串緩衝區,管理插入到此緩衝區的新文本片斷,並僅在文本長度超出字串緩衝區長度時對字串進行重新分配。Microsoft .NET 架構免費提供了這樣一個類 (System.Text.StringBuilder),並建議在該環境下進行的所有字串串連操作中使用它。在 ASP 和傳統的 Visual Basic 環境中,我們無法訪問此類,因此需要自行建立。下面是使用 Visual Basic 6.0 建立的 StringBuilder 類樣本(為簡潔起見,省略了錯誤處理代碼)。
  
  Option Explicit
  
  ' 預設的緩衝區初始大小和增長係數
  Private Const DEF_INITIALSIZE As Long = 1000
  Private Const DEF_GROWTH As Long = 1000
  
  ' 緩衝區大小和增長
  Private m_nInitialSize As Long
  Private m_nGrowth As Long
  
  ' 緩衝區和緩衝區計數器
  Private m_sText As String
  Private m_nSize As Long
  Private m_nPos As Long
  
  Private Sub Class_Initialize()
  ' 設定大小和增長的預設值
  m_nInitialSize = DEF_INITIALSIZE
  m_nGrowth = DEF_GROWTH
  ' 初始化緩衝區
  InitBuffer
  End Sub
  
  ' 設定初始大小和增長數量
  Public Sub Init(ByVal InitialSize As Long, ByVal Growth As Long)
  If InitialSize > 0 Then m_nInitialSize = InitialSize
  If Growth > 0 Then m_nGrowth = Growth
  End Sub
  
  ' 初始化緩衝區
  Private Sub InitBuffer()
  m_nSize = -1
  m_nPos = 1
  End Sub
  
  ' 增大緩衝區
  Private Sub Grow(Optional MinimimGrowth As Long)
  ' 初始化緩衝區(如有必要)
  If m_nSize = -1 Then
  m_nSize = m_nInitialSize
  m_sText = Space$(m_nInitialSize)
  Else
  ' 只是增長
  Dim nGrowth As Long
  nGrowth = IIf(m_nGrowth > MinimimGrowth,
  m_nGrowth, MinimimGrowth)
  m_nSize = m_nSize + nGrowth
  m_sText = m_sText & Space$(nGrowth)
  End If
  End Sub
  
  ' 將緩衝區大小調整到當前使用的大小



聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.