为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 C# 中有效地将列表中对象的属性导出到 CSV?

如何在 C# 中有效地将列表中对象的属性导出到 CSV?

C#
三国纷争 2023-07-09 10:28:13
基本上我有一个需要编辑的数据库导入/导出文件(文件有 140 万行)。编辑速度相当快,尽管我必须遍历所有行并检查 2 个字段的长度是否正确,如果不正确,只需将其填充到正确的长度。我遇到的问题是导出到 csv 文件确实无效。我目前正在使用我创建的方法,该方法基本上创建一个字符串,然后使用列表中的每个对象创建一个新行(如下面的代码所示)。问题是它进展得很慢。我猜它相当慢,因为列表中的所有对象都有 14 个参数被放入字符串中(代码经过编辑,所以不是那么长)。但有什么办法可以让它更快吗?public static string CsvExport(List<DataLine> inputList)        {            string exportString = "";            string delimiter = ";";            foreach (DataLine line in inputList)            {                exportString += line.SCREENINGREQUESTUNIQUEID + delimiter + line.REQUESTTIMESTAMP + "\n";            }            return exportString;        }
查看完整描述

2 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

第一的。使用正确的工具来完成工作 - StringBuilder

var exportString = lines

    .Aggregate(

        new StringBuilder(), 

        (builder, line) => 

        {

            builder.Append(line.SCREENINGREQUESTUNIQUEID);

            builder.Append(";"); 

            builder.AppendLine(line.REQUESTTIMESTAMP);


            return builder;

        })

    .ToString();

请注意,带有+运算符的字符串连接将在每次+使用时实例化新的字符串实例,其中先前的字符串实例仍将保留在内存中(对于 1M 行,这将变得很重要)。您可以StringBuilder有效地完成此操作,而无需实例化新对象,并使用整个文件所需的确切内存量,而无需复制以前的值,正如托马斯在他的回答中提到的那样。


第二。如果您将文本写入文件,您可以使用StreamWriter以更节省内存的方式执行此操作(但可能速度效率不高)


using (var csv = new StreamWriter("pathToFile"))

{

    foreach (var line in lines)

    {

        csv.Write(line.SCREENINGREQUESTUNIQUEID);

        csv.Write(";"); 

        csv.WriteLine(line.REQUESTTIMESTAMP);

    }

}


查看完整回答
反对 回复 2023-07-09
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

您说需要导出到 CSV 文件,但实际上,您导出到 RAM 中的字符串。

像您一样在字符串上使用+=将创建至少 140 万个临时字符串,这些字符串都需要进行垃圾收集。如果每行有 100 个字符长,则内存吞吐量为

200 + 400 + 600 + ...

有 140 万个术语。即 200 * sum(1..1.4M) 或 ~ 200 TB。以 DDR3 1333 = 10.6 GB/s 的速率计算,这将需要大约 20000 秒或 5:30 小时

使用StreamWriter写入文件。这将为您节省大量 RAM 内存,减少内存并提高速度,因为在您仍在计算时就已经可以写入磁盘了。


查看完整回答
反对 回复 2023-07-09
  • 2 回答
  • 0 关注
  • 75 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信