5

Microsoft(和许多开发人员)声称SqlDataReader.GetOrdinal 方法提高了从 DataReader 检索值的性能,而不是使用命名查找,即。读者[“列名”]。问题是,如果处理小的分页记录集,真正的性能差异是什么?是否值得在整个代码中查找和引用序数索引的额外开销?

4

4 回答 4

6

Microsoft 建议不要在循环中调用 GetOrdinal。

这将包括使用字符串索引器的间接调用。

您可以在循环顶部使用 GetOrdinal 将序数放入数组中,并使数组中的索引为 const 或为它们设置一个枚举(根本没有 GetOrdinal),或者将 GetOrdinal 用于具有描述性名称的单个变量。

只有当你的集合很小时,我才会真正认为这是过早的优化。

显然是3%的罚款。

于 2011-05-02T18:03:55.317 回答
5

任何差异都将超过维护开销。

如果您有那么多数据会产生明显的差异,我建议您的客户端代码中有太多数据。或者这是您考虑使用序数而不是名称的时候

于 2011-05-02T19:19:43.523 回答
2

是和不是。

如果您正在处理大量数据,那么您肯定会从使用序数而不是列名中受益。

否则,请保持简单、易读且更安全 - 并坚持使用列名。

仅在需要时进行优化。

于 2011-05-02T17:53:12.263 回答
-1

我为 SqlDataReader 创建了一个包装器,它将 orindals 存储在以列名作为键的字典中。

如果有人更改从存储过程返回的列顺序,它给我带来了有序的性能提升,同时保持代码更具可读性并且不太可能中断。

Friend Class DataReader
Implements IDisposable

Private _reader As SqlDataReader
Private _oridinals As Dictionary(Of String, Integer)
Private Shared _stringComparer As StringComparer = StringComparer.OrdinalIgnoreCase 'Case in-sensitive

Public Sub New(reader As SqlDataReader)
    Me._reader = reader
    Me.SetOrdinals()
End Sub

Private Sub SetOrdinals()
    Me._oridinals = New Dictionary(Of String, Integer)(_stringComparer)
    For i As Integer = 0 To Me._reader.FieldCount - 1
        Me._oridinals.Add(Me._reader.GetName(i), i)
    Next
End Sub

Public Function Read() As Boolean
    Return Me._reader.Read()
End Function

Public Function NextResult() As Boolean
    Dim value = Me._reader.NextResult()
    If value Then
        Me.SetOrdinals()
    End If
    Return value
End Function

Default Public ReadOnly Property Item(name As String) As Object
    Get
        Return Me._reader(Me.GetOrdinal(name))
    End Get
End Property

Public Function GetOrdinal(name As String) As Integer
    Return Me._oridinals.Item(name)
End Function

Public Function GetInteger(name As String) As Integer
    Return Me._reader.GetInt32(Me.GetOrdinal(name))
End Function

Public Function GetString(ordinal As Integer) As String
    Return Me._reader.GetString(ordinal)
End Function

Public Function GetString(name As String) As String
    Return Me._reader.GetString(Me.GetOrdinal(name))
End Function

Public Function GetDate(name As String) As Date
    Return Me._reader.GetDateTime(Me.GetOrdinal(name))
End Function

Public Function GetDateNullable(name As String) As Nullable(Of Date)
    Dim o = Me._reader.GetValue(Me.GetOrdinal(name))
    If o Is System.DBNull.Value Then
        Return Nothing
    Else
        Return CDate(o)
    End If
End Function

Public Function GetDecimal(name As String) As Decimal
    Return Me._reader.GetDecimal(Me.GetOrdinal(name))
End Function

Public Function GetBoolean(name As String) As Boolean
    Return Me._reader.GetBoolean(Me.GetOrdinal(name))
End Function

Public Function GetByteArray(name As String) As Byte()
    Return CType(Me._reader.GetValue(Me.GetOrdinal(name)), Byte())
End Function

Public Function GetBooleanFromYesNo(name As String) As Boolean
    Return Me._reader.GetString(Me.GetOrdinal(name)) = "Y"
End Function

'Disposable Code

End Class
于 2011-08-25T17:27:40.587 回答