关于c#:在大数据表中设置DataRow值的性能

Performance of setting DataRow values in a large DataTable

我有一个很大的 DataTable - 大约 15000 行和 100 列 - 我需要为每一行中的一些列设置值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Creating the DataTable
DataTable dt = new DataTable();
for (int i = 0; i < COLS_NUM; i++)
{
    dt.Columns.Add("COL" + i);
}    
for (int i = 0; i < ROWS_NUM; i++)
{
    dt.Rows.Add(dt.NewRow());
}

// Setting several values in every row
Stopwatch sw2 = new Stopwatch();
sw2.Start();
foreach (DataRow row in dt.Rows)
{
    for (int j = 0; j < 15; j++)
    {
        row["Col" + j] = 5;
    }
}
sw2.Stop();

上面测得的时间约为4.5秒。有什么简单的方法可以改善吗?

  • 循环 ROWS_NUM 并创建新行时,是否可以在那里初始化列值?这将节省使用第三个循环。
  • 初始化仅用于此示例,在实际情况下,DataTable 来自数据库。


在填充数据之前,请在 DataTable 上调用 BeginLoadData() 方法。完成数据加载后,调用 EndLoadData()。这将关闭所有通知、索引维护和约束,从而提高性能。

作为替代方法,在更新每一行之前调用 BeginEdit(),并在该行的编辑完成时调用 EndEdit()。

这是一个链接,其中包含有关提高 DataSet 性能的更多信息:
http://www.softwire.com/blog/2011/08/04/dataset-performance-in-net-web-applications/


我能想到的一个改进是通过索引而不是名称来编辑列。

1
2
3
4
5
6
7
foreach (DataRow row in dt.Rows)
{
    for (int j = 0; j < 15; j++)
    {
        row[j] = 5;
    }
}

通过经验测试,您的方法在我的计算机上运行时间约为 1500 毫秒,而这个基于索引的版本运行时间约为 1100 毫秒。

另外,请参阅 Marc 在这篇文章中的回答:

在没有for循环的情况下为数据表中的所有行设置值

  • 当我测试它时,这略微提高了性能(大约 10%),尽管我仍然希望有更多。如果没有更重要的事情出现,我会接受。
  • 我知道这听起来不太好,但我认为最好的方法是不在 DataTable 中加载 15000 行。你确定你需要一次加载它们吗?也许最好检查一下系统的设计。
  • 特定场景下的设计并不理想,这一点毋庸置疑,但现在更容易进行改进而不是重新设计。我最终做了什么 - 1)使用列索引而不是名称。 2) 创建动态列时,给它们一个默认值(在几乎零时间内应用于所有现有行),然后仅在它们与默认值不同时才分配行值。


这取决于您的业务逻辑,这在您的问题中并不清楚,但是,如果您想为每一行中的某些列设置值,请尝试以下操作,

  • 创建一个单独的临时列,您可以在同一列中创建它
    创建原始数据表时循环

  • 将新值填入此列,

  • 删除旧列并在其位置插入新列。

如果您可以期待新值,或者如果您对所有行都有相同的值(如您的示例中),或者如果您有某种重复,则此解决方案将是合乎逻辑的,在这种情况下,添加一个加载的新列将比循环所有行要快得多。