6

我有一堆DataTables需要转换为object[,]数组(不是 object[][]数组)。就性能而言,最有效的方法是什么?

我知道我可以通过object[dt.Rows.Count, dt.Columns.Count]最初构建我的方法来做到这一点,然后遍历行并将每一行解析到数组中的一个位置,但我相当确定还有其他方法,例如使用 Linq 或 System.Data 特定功能,例如dataRow.ToItemArray()可能更有效率。

DataTables的大小可变,除了字符串之外,还包含需要适当格式化的日期和数字。

例如,如果我的一个数据表包含

ID 名称 日期 值
1 雷切尔 2013 年 1 月 1 日 00:00:00 100.0000
2 约瑟夫 2012 年 3 月 31 日 00:00:00 50.0000
3 莎拉 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

1 回答 1

8

基本上我们需要:

  1. 分配内存object[,]

    我们在这里不能做太多......我们需要确保我们分配一次内存,而不是再次重新分配它。所以很明显我们需要立即创建数组,而不是使用List.Add(...)内部重新分配内存块之类的操作。

  2. 然后,我们需要将对象从行项复制到多维数组中。Buffer.BlockCopy当我们处理对象时,我们不能在这里使用。自然地,我们不能依赖任何memcpy类似的行为,因为每个对象的 CLR 都需要复制其引用,或者对值类型执行 unbox->copy in heap->box。所以,最简单的方法就是 for.. for.. style。

因此,看起来大多数性能解决方案都是直观的:

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;
}
于 2013-04-04T14:36:34.483 回答