2013-04-04 147 views
5

我有一堆DataTables需要轉換爲object[,]陣列(而不是object[][]陣列)。在性能方面做什麼最有效的方法是什麼?什麼是將DataTable轉換爲對象的最有效方法[,]?

我知道我可以通過最初構建我的object[dt.Rows.Count, dt.Columns.Count]來完成此操作,然後遍歷行並將每行解析到數組中的某個位置,但我確信還有其他方法,如使用Linq或System.Data特定諸如dataRow.ToItemArray()之類的特徵可能更有效。

我的DataTables是可變大小的,並且包含日期和數字,除了字符串之外,還需要適當格式化。

例如,如果我的數據表中的一個包含

 
Id Name Date     Value 
1  Rachel 1/1/2013 00:00:00 100.0000 
2  Joseph 3/31/2012 00:00:00 50.0000 
3  Sarah 2/28/2013 00:00:00 75.5000 

然後我希望的object[,]陣列包含完全相同的數據(理想地與頭),而是用格式的日期和值

arr[x,0] = row[x].Field<int>("Id"); 
arr[x,1] = row[x].Field<string>("Name"); 
arr[x,2] = row[x].Field<DateTime>("Date").ToString("M/d/yy"); 
arr[x,3] = row[x].Field<decimal>("Value").ToString("C2"); // Currency format 
+4

使用LINQ不會奇蹟般地加快東西。 – 2013-04-04 13:54:38

+0

通過「更高效」,您是否希望改進算法的時間複雜度(如O(n^2)到O(n)),還是隻是一個常數因子改進? – mbeckish 2013-04-04 13:55:18

+1

爲什麼你不在帖子中包含「之前」和「之後」的數據? – 2013-04-04 13:59:04

回答

8

基本上,我們需要:

  1. 分配內存object[,]

    這裏我們不能做太多的事情..我們需要確保一次分配內存,而不是重新分配一次。所以很明顯我們需要一次創建數組,而不使用內部重新分配內存塊的操作,如List.Add(...)

  2. 然後,我們需要將行項目中的對象複製到多維數組中。我們在這裏處理對象時不能使用Buffer.BlockCopy。當然,我們不能依賴任何類似於memcpy的行爲,因爲每個對象的CLR都需要複製其引用,或者對於值類型執行unbox-> copy in heap-> box。所以,最簡單的方法將只是.. for ..風格。

所以,看起來像極高性能的解決方案這裏是一個直觀:

public static object[,] Convert(DataTable dt) 
{ 
    var rows = dt.Rows; 
    int rowCount = rows.Count; 
    int colCount = dt.Columns.Count; 
    var result = new object[rowCount, colCount]; 

    for (int i = 0; i < rowCount; i++) 
    { 
     var row = rows[i]; 
     for (int j = 0; j < colCount; j++) 
     { 
      result[i, j] = row[j]; 
     } 
    } 

    return result; 
} 
相關問題