簡體   English   中英

按名稱而不是按索引查找 DataTable 中的列是否會增加開銷?

[英]Is there added overhead to looking up a column in a DataTable by name rather than by index?

DataTable對象中,通過名稱thisRow("ColumnA")而不是通過列索引thisRow(0)查找列值是否會增加開銷? 在哪些情況下這可能是一個問題。

我在一個有很多編寫 VB6 代碼經驗的團隊工作,我注意到沒有按名稱對DataTable對象或數據網格進行列查找。 即使在 .NET 代碼中,我們也使用一組整數常量來引用這些類型對象中的列名。 我問我們的團隊負責人為什么會這樣,他提到在 VB6 中,按列名而不是按索引查找數據有很多開銷。 .NET 仍然如此嗎?


示例代碼(在 VB.NET 中,但同樣適用於 C#):

Public Sub TestADOData()
Dim dt As New DataTable

'Set up the columns in the DataTable    '
dt.Columns.Add(New DataColumn("ID", GetType(Integer)))
dt.Columns.Add(New DataColumn("Name", GetType(String)))
dt.Columns.Add(New DataColumn("Description", GetType(String)))

'Add some data to the data table    '
dt.Rows.Add(1, "Fred", "Pitcher")
dt.Rows.Add(3, "Hank", "Center Field")

'Method 1: By Column Name   '
For Each r As DataRow In dt.Rows
  Console.WriteLine( _
   "{0,-2} {1,-10} {2,-30}", r("ID"), r("Name"), r("Description"))
Next

Console.WriteLine()

'Method 2: By Column Name   '
For Each r As DataRow In dt.Rows
  Console.WriteLine("{0,-2} {1,-10} {2,-30}", r(0), r(1), r(2))
Next

End Sub

是否存在方法 2 比方法 1 提供性能優勢的情況?

是的,按名稱而不是按索引查找列應該有輕微的開銷。 我不會擔心,除非您在循環中不斷查找同一列,就像在您的代碼示例中一樣。 因為這樣,輕微的開銷可能會累積為可測量的開銷,具體取決於表的行數。

訪問某行的特定列值的最快方法使用DataColumn對象本身進行查找 例如:

Dim dt As DataTable = ...

Dim idColumn As DataColumn = dt.Columns("ID")
Dim nameColumn As DataColumn = dt.Columns("Name")
Dim descriptionColumn As DataColumn = dt.Columns("Description")

For Each r As DataRow In dt.Rows

    ' NB: lookup through a DataColumn object, not through a name, nor an index: '
    Dim id = r(idColumn)
    Dim name = r(nameColumn)
    Dim description = r(descriptionColumn)

    ...
Next

最后一條建議:我強烈建議您不要使用數字索引! 它使您的代碼更脆弱,也更難以理解和維護:一旦列的邏輯順序發生變化,您就需要相應地調整您的代碼,可能在幾個地方(並且您可能很容易監督其中一個,導致到錯誤)。 如果您改為使用列名或DataColumn對象本身進行查找,則可以更改列的順序而無需更改其余代碼。

事實是

  1. 按索引獲取列是對 ArrayList 的直接索引
  2. 如果名稱查找區分大小寫,則執行哈希表查找
  3. 如果名稱查找不區分大小寫,則會掃描列表中的名稱,並執行成本更高的區域敏感字符串比較。

因此,按索引檢索肯定是性能最高的,但這有關系嗎?

在我的機器上做一些基本的(閱讀天真的)測試,我發現使用提到的索引機制對列進行 1,000,000 次訪問需要以下時間

  1. 直接索引 - 13.3ms
  2. 不區分大小寫的查找 - 109.11ms
  3. 區分大小寫的查找 - 109.24ms

因此,根據您的情況,您可以得出結論。

是的,按名稱而不是絕對索引查找列會產生開銷(因為它只是定位列,然后以這種方式訪問​​它)。

話雖如此,這是相當不成熟的優化。 DataTable將首先嘗試以區分大小寫的方式定位列,這非常快。 如果它不能以這種方式定位該列,它會以不區分大小寫的方式查找,這只是稍微慢了一點。

訪問數據的絕對最快方法是通過DataColumn對象本身,因為這是基於索引和基於名稱的訪問器使用的。

最好的方法是按列名查找索引並使用索引來定位列:

Dim table As DataTable = ...
Dim foo As int = table.Columns("Foo")

For Each row As DataRow In table.Rows
    Dim data = row(foo)
Next

您正在按索引查找,您還可以從名稱猜測您正在閱讀的列。 另一個優點是,如果您更改“選擇”查詢中字段的順序,您仍將獲得正確的值。 另一方面,如果您對索引進行硬編碼,您的代碼將會中斷。

取決於你使用它的地方。 在桌面應用程序啟動時,這些小的低效率可能會累積成長時間的延遲。 在鼠標和鍵盤事件上很可能不會。 與優化此類低級內容相比,花時間進行函數分析(將執行時間打印到 dbgview)很可能更有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM