十、用哪種方法引用記錄集字段值效率最高?
10.1 測試
至此為止我們一直通過名字引用記錄集中的字段值。由于這種方法要求每次都必須尋找相應(yīng)的字段,它的效率并不高。為證明這一點,下面這個測試中我們通過字段在集合中的索引引用它的值(ADO__08.asp): 'write data Do While Not objRS.EOF Response.Write( _ "< TR >" & _ "< TD >" & objRS(0) & "< /TD >" & _ "< TD >" & objRS(1) & "< /TD >" & _ "< TD >" & objRS(2) & "< /TD >" & _ "< TD >" & objRS(3) & "< /TD >" & _ "< TD >" & objRS(4) & "< /TD >" & _ "< TD >" & objRS(5) & "< /TD >" & _ "< TD >" & objRS(6) & "< /TD >" & _ "< /TR > " _ ) objRS.MoveNext Loop
和預(yù)期的一樣,頁面開銷也有小小的變化(這或許是因為代碼略有減少)。然而,這種方法在顯示時間上的改善是相當(dāng)明顯的。
在下一個測試中,我們把所有的字段分別綁定到變量(ADO__09.asp): If objRS.EOF Then Response.Write("No Records Found") Else 'write headings ... Dim fld0 Dim fld1 Dim fld2 Dim fld3 Dim fld4 Dim fld5 Dim fld6
Set fld0 = objRS(0) Set fld1 = objRS(1) Set fld2 = objRS(2) Set fld3 = objRS(3) Set fld4 = objRS(4) Set fld5 = objRS(5) Set fld6 = objRS(6)
'write data Do While Not objRS.EOF Response.Write( _ "< TR >" & _ "< TD >" & fld0 & "< /TD >" & _ "< TD >" & fld1 & "< /TD >" & _ "< TD >" & fld2 & "< /TD >" & _ "< TD >" & fld3 & "< /TD >" & _ "< TD >" & fld4 & "< /TD >" & _ "< TD >" & fld5 & "< /TD >" & _ "< TD >" & fld6 & "< /TD >" & _ "< /TR >" _ ) objRS.MoveNext Loop
Set fld0 = Nothing Set fld1 = Nothing Set fld2 = Nothing Set fld3 = Nothing Set fld4 = Nothing Set fld5 = Nothing Set fld6 = Nothing
Response.Write("< /TABLE >") End If
這是目前為止最好的記錄。請注意單個記錄的顯示時間已經(jīng)降低到0.45毫秒以下。
上述腳本都要求對結(jié)果記錄集的構(gòu)造有所了解。例如,我們在列標(biāo)題中直接使用了字段名字,單獨地引用各個字段值。下面這個測試中,不僅字段數(shù)據(jù)通過遍歷字段集合得到,而且字段標(biāo)題也用同樣的方式得到,這是一種更為動態(tài)的方案(ADO__10.asp)。 If objRS.EOF Then Response.Write("No Records Found") Else 'write headings Response.Write("< TABLE BORDER=1 >< TR >") For Each objFld in objRS.Fields Response.Write("< TH >" & objFld.name & "< /TH >") Next Response.Write("< /TR >")
'write data Do While Not objRS.EOF Response.Write("< TR >") For Each objFld in objRS.Fields Response.Write("< TD >" & objFld.value & "< /TD >") Next Response.Write("< /TR >") objRS.MoveNext Loop Response.Write("< /TABLE >") End If
可以看到,代碼性能有所下降,但它仍舊要比ADO__07.asp要快。
下一個測試示例是前面兩個方法的折衷。我們將繼續(xù)保持動態(tài)特征,同時通過在動態(tài)分配的數(shù)組中保存字段引用提高性能: If objRS.EOF Then Response.Write("No Records Found") Else Dim fldCount fldCount = objRS.Fields.Count Dim fld() ReDim fld(fldCount) Dim i For i = 0 to fldCount-1 Set fld(i) = objRS(i) Next
'write headings Response.Write("< TABLE BORDER=1 >< TR >") For i = 0 to fldCount-1 Response.Write("< TH >" & fld(i).name & "< /TH >") Next Response.Write("< /TR >")
'write data Do While Not objRS.EOF Response.Write("< TR >") For i = 0 to fldCount-1 Response.Write("< TD >" & fld(i) & "< /TD >") Next Response.Write("< /TR >") objRS.MoveNext Loop
For i = 0 to fldCount-1 Set fld(i) = Nothing Next Response.Write("< /TABLE >") End If
雖然還不能超過以前最好的成績,但它比開頭的幾個示例要快,同時它具有動態(tài)地處理任何記錄集這一優(yōu)點。
與前面的測試代碼相比,下面的測試代碼有了根本性的改動。它使用記錄集對象的GetRows方法填充數(shù)組以供循環(huán)訪問數(shù)據(jù),而不是直接訪問記錄集本身。注意在調(diào)用GetRows之后立即把Recordset設(shè)置成了Nothing,也就是盡快地釋放了系統(tǒng)資源。另外,請注意數(shù)組的第一維代表字段,第二維代表行(ADO__12.asp)。 If objRS.EOF Then Response.Write("No Records Found") objRS.Close Set objRS = Nothing Else 'write headings ...
'set array Dim arrRS arrRS = objRS.GetRows
'close recordset early objRS.Close Set objRS = Nothing
'write data Dim numRows Dim numFlds Dim row Dim fld numFlds = Ubound(arrRS, 1) numRows = Ubound(arrRS, 2) For row= 0 to numRows Response.Write("< TR >") For fld = 0 to numFlds Response.Write("< TD >" & arrRS(fld, row) & "< /TD >") Next Response.Write("< /TR >") Next
Response.Write("< /TABLE >") End If
使用GetRows方法時,整個記錄集都被提取到了數(shù)組。雖然記錄集極端龐大時可能產(chǎn)生資源問題,但是用循環(huán)訪問數(shù)據(jù)的速度確實更快了,這是由于取消了MoveNext和檢查EOF之類的函數(shù)調(diào)用。
速度是要付出代價的,現(xiàn)在記錄集的元數(shù)據(jù)已經(jīng)丟失了。為解決這個問題,我們可以在調(diào)用GetRows之前從記錄集對象提取標(biāo)題信息;此外,數(shù)據(jù)類型和其他信息也可以預(yù)先提取。另外還要注意的是,測試中性能上的優(yōu)勢只有在記錄集較大的時候才會出現(xiàn)。
這一組的最后一個測試中,我們使用了記錄集的GetString方法。GetString方法將整個記錄集提取成為一個大的字符串,并允許指定分隔符(ADO__13.asp): If objRS.EOF Then Response.Write("No Records Found") objRS.Close Set objRS = Nothing Else 'write headings ...
'set array Dim strTable strTable = objRS.GetString (2, , "< /TD >< TD >", "< /TD >< /TR >< TR >< TD >")
'close recordset early objRS.Close Set objRS = Nothing
Response.Write(strTable & "< /TD >< /TR >< /TABLE >") End If
雖然這種方法在速度上的好處非常明顯,但它只適用于最簡單的操作,根本無法適應(yīng)稍微復(fù)雜的數(shù)據(jù)操作要求。
10.2 意見
在進(jìn)行這一組的測試之前,完成單個記錄的時間徘徊在0.83毫秒左右,這組測試中的大多數(shù)結(jié)果使這個數(shù)字減半。其中某些測試實例具有無與倫比的性能表現(xiàn),但這些代碼損失了適應(yīng)能力。
因此,我們得到的是下面幾條較有價值的規(guī)則:
如果記錄集中的數(shù)據(jù)不需要分別操作而且可以用一致的方式格式化,使用GetString方法提取數(shù)據(jù)。 如果要求有更靈活的格式,但不需要用到記錄集的元數(shù)據(jù),使用GetRows將數(shù)據(jù)提取到數(shù)組。 如果要求有更靈活的格式,同時要用到記錄集的元數(shù)據(jù),在進(jìn)入數(shù)據(jù)提取循環(huán)之前將字段綁定到變量。 始終避免通過名字引用字段。 (出處:熱點網(wǎng)絡(luò))
|