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

基本上我有一个需要编辑的数据库导入/导出文件(文件有 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;

        }


三国纷争
浏览 76回答 2
2回答

慕田峪9158850

第一的。使用正确的工具来完成工作 - StringBuildervar 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);    }}

眼眸繁星

您说需要导出到 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 内存,减少内存并提高速度,因为在您仍在计算时就已经可以写入磁盘了。
打开App,查看更多内容
随时随地看视频慕课网APP