在 VB6 中,我們使用 On Error 來捕獲和處理錯誤,而且經(jīng)常使用 On Error Resume Next 來可能產(chǎn)生的忽略錯誤。
那么 使用錯誤捕獲是否會影響速度呢?
是的,使用錯誤處理將會降低一些性能,在。Net 中,使用 Try Catch 也將會影響性能,所以我們使用Reflector 反編譯微軟的類庫時,會發(fā)現(xiàn)他的子過程很少使用 Try 來捕獲錯誤,基本都是采用可預(yù)知的方式來判斷可能出現(xiàn)的錯誤,并做相應(yīng)處理。
實際上,使用錯誤捕獲后,編譯后的代碼實際上做了很多不為我們所知的操作,雖然 使用錯誤捕獲從一定程度上方便了編碼過程,卻犧牲了一定的速度,有利有弊,所以我們應(yīng)該正確的使用 錯誤捕獲。
測試的VB6代碼
Option Explicit
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim m_FldsName() As String
Private Sub Command1_Click()
Dim II As Long
Dim t As Single
cn.Open "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=廣商;Data Source=SUPER"
rs.Open "Select * from FldSet ", cn, adOpenKeyset
Do Until rs.EOF = True
rs.MoveNext
Loop
rs.MoveFirst
t = Timer
ReDim m_FldsName(rs.Fields.Count)
For II = 0 To rs.Fields.Count - 1
m_FldsName(II) = rs.Fields(II).Name
Next
Do Until rs.EOF = True
ReadFieldsNotOnErr "Err1"
ReadFieldsNotOnErr "TableName"
ReadFieldsNotOnErr "Err2"
rs.MoveNext
Loop
MsgBox "NotErr:" & Timer - t
On Error Resume Next
rs.MoveFirst
t = Timer
Do Until rs.EOF = True
ReadFieldsOnErr "Err1"
ReadFieldsOnErr "TableName"
ReadFieldsOnErr "Err2"
rs.MoveNext
Loop
MsgBox "OnErr:" & Timer - t
rs.Close
cn.Close
End Sub
Private Sub ReadFieldsOnErr(FieldName As String)
Dim v As Variant
v = rs(FieldName).Value
End Sub
Private Sub ReadFieldsNotOnErr(FieldName As String)
Dim II As Long
Dim IsExists As Boolean
Dim v As Variant
IsExists = False
For II = 0 To UBound(m_FldsName) - 1
If m_FldsName(II) = FieldName Then
IsExists = True
Exit For
End If
Next
If IsExists = True Then
v = rs(FieldName).Value
End If
End Sub
===================================
測試結(jié)果:
無錯誤時
ReadFieldsOnErr : 0。46
ReadFieldsNotOnErr : 0。47
有錯誤時
ReadFieldsOnErr : 0.96
ReadFieldsNotOnErr : 0.47
可以看到:不使用錯誤處理,速度相當(dāng)穩(wěn)定,而使用錯誤處理時,有錯誤的情況下速度落差較大。所以 對于在循環(huán)中 頻繁調(diào)用 的子過程,建議對可能出現(xiàn)的錯誤進(jìn)行預(yù)處理,減少使用 On error來提升速度。
那么 使用錯誤捕獲是否會影響速度呢?
是的,使用錯誤處理將會降低一些性能,在。Net 中,使用 Try Catch 也將會影響性能,所以我們使用Reflector 反編譯微軟的類庫時,會發(fā)現(xiàn)他的子過程很少使用 Try 來捕獲錯誤,基本都是采用可預(yù)知的方式來判斷可能出現(xiàn)的錯誤,并做相應(yīng)處理。
實際上,使用錯誤捕獲后,編譯后的代碼實際上做了很多不為我們所知的操作,雖然 使用錯誤捕獲從一定程度上方便了編碼過程,卻犧牲了一定的速度,有利有弊,所以我們應(yīng)該正確的使用 錯誤捕獲。
測試的VB6代碼
Option Explicit
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim m_FldsName() As String
Private Sub Command1_Click()
Dim II As Long
Dim t As Single
cn.Open "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=廣商;Data Source=SUPER"
rs.Open "Select * from FldSet ", cn, adOpenKeyset
Do Until rs.EOF = True
rs.MoveNext
Loop
rs.MoveFirst
t = Timer
ReDim m_FldsName(rs.Fields.Count)
For II = 0 To rs.Fields.Count - 1
m_FldsName(II) = rs.Fields(II).Name
Next
Do Until rs.EOF = True
ReadFieldsNotOnErr "Err1"
ReadFieldsNotOnErr "TableName"
ReadFieldsNotOnErr "Err2"
rs.MoveNext
Loop
MsgBox "NotErr:" & Timer - t
On Error Resume Next
rs.MoveFirst
t = Timer
Do Until rs.EOF = True
ReadFieldsOnErr "Err1"
ReadFieldsOnErr "TableName"
ReadFieldsOnErr "Err2"
rs.MoveNext
Loop
MsgBox "OnErr:" & Timer - t
rs.Close
cn.Close
End Sub
Private Sub ReadFieldsOnErr(FieldName As String)
Dim v As Variant
v = rs(FieldName).Value
End Sub
Private Sub ReadFieldsNotOnErr(FieldName As String)
Dim II As Long
Dim IsExists As Boolean
Dim v As Variant
IsExists = False
For II = 0 To UBound(m_FldsName) - 1
If m_FldsName(II) = FieldName Then
IsExists = True
Exit For
End If
Next
If IsExists = True Then
v = rs(FieldName).Value
End If
End Sub
===================================
測試結(jié)果:
無錯誤時
ReadFieldsOnErr : 0。46
ReadFieldsNotOnErr : 0。47
有錯誤時
ReadFieldsOnErr : 0.96
ReadFieldsNotOnErr : 0.47
可以看到:不使用錯誤處理,速度相當(dāng)穩(wěn)定,而使用錯誤處理時,有錯誤的情況下速度落差較大。所以 對于在循環(huán)中 頻繁調(diào)用 的子過程,建議對可能出現(xiàn)的錯誤進(jìn)行預(yù)處理,減少使用 On error來提升速度。