5

我正在将文件中的 csv 数据加载到数据表中进行处理。

问题是,我想处理几个文件,我对数据表的测试显示我使用 37MB csv 文件测试的巨大内存消耗,内存增长到 240MB,恕我直言。我读到,数据表中有开销,我可以忍受大约 70MB 的大小,但不是 240MB,这意味着它是原始大小的六倍。我在这里读到,数据表需要比 POCO 更多的内存,但差别太大了。

我戴上内存分析器并查看是否有内存泄漏以及内存在哪里。我发现,datatablecolumns 有 6MB 到 19MB 的空间填充了字符串,并且 datatable 有大约 20 列。值是否存储在列中?为什么要占用这么多内存,我该怎么做才能减少内存消耗。有了这种内存消耗,数据表似乎无法使用。

有其他人对数据表有这样的问题,还是我做错了什么?

PS:我尝试了一个70MB的文件,数据表增长到了500MB!

好的,这是一个小测试用例:37MB 的 csv 文件(21 列)让内存增长到 179MB。

    private static DataTable ReadCsv()
    {
        DataTable table = new DataTable();
        table.BeginLoadData();

        using (var reader = new StreamReader(File.OpenRead(@"C:\Develop\Tests\csv-Data\testdaten\test.csv")))
        {               
            int y = 0;
            int columnsCount = 0;
            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();
                var values = line.Split(',');

                if (y == 0)
                {
                    columnsCount = values.Count();
                    // create columns
                    for (int x = 0; x < columnsCount; x++)
                    {
                        table.Columns.Add(new DataColumn(values[x], typeof(string)));
                    }
                }
                else
                {
                    if (values.Length == columnsCount)
                    {
                        // add the data
                        table.Rows.Add(values);
                    }
                }

                y++;
            }

            table.EndLoadData();
            table.AcceptChanges();

        }

        return table;
    }
4

2 回答 2

5

DataSet及其子DataTable,DataRow等组成内存中的关系数据库。涉及很多开销(尽管它确实使[某些]事情非常方便。

如果内存是个问题,

  • 构建域对象以使用类型属性表示 CSV 文件中的每一行。
  • 创建一个自定义集合(或仅用于 IList<T>保存它们
  • 或者,使用 a 的基本语义构建一个轻量级类DataTable
    • 按数字选择行的能力
    • 能够按行号和列名或编号选择行中的列。
    • 知道有序的列名集的能力
    • 奖励:能够按名称或序号选择一列并接收其值列表,每行一个。

您确定需要 CSV 文件的内存表示吗?您可以通过IDataReader类似 Sebastien Lorion 的快速 CSV 阅读器访问它们吗?

于 2013-08-26T17:50:13.107 回答
0

DataTables 是将表格数据放入内存并添加大量与表格相关的功能的通用解决方案。如果开销对您来说是不可接受的,您可以选择 1) 编写自己的 DataTable 类,以消除不需要的开销 2) 使用仍然可以完成您需要的替代表示,可能基于 POCO,或者可能是 XMLDocument (可能有同样多的开销,也许更多,从来没有真正担心过)。3)停止尝试将所有内容加载到内存中,只需根据需要从外部存储中引入数据。

于 2013-08-26T17:06:35.253 回答