有你在真好 的个人博客
如何使用C#从CSV加载500万条记录并在3秒钟内处理它们
阅读:2197 添加日期:2021/3/27 23:15:51 原文链接:https://www.toutiao.com/item/6940835359076975134/

我们有一个场景,需要使用C#在2秒内从CSV文件加载500万条记录,然后根据某些条件对其进行处理并返回一些已处理的记录。这听起来像是加载和处理可能会花费更多时间,但前提是我们采用了错误的方式。

这是我们将在下面的代码中解决的问题。

让我们来做一些处理。首先从下面的URL下载一个文件,它是一个带有500万条记录的销售记录CSV文件示例。

http://eforexcel.com/wp/wp-content/uploads/2020/09/5m-Sales-Records.7z

现在我们要做的是在程序中加载这个CSV并按顺序获得收入最高的前10个销售记录。

Stopwatch stopwatch = new Stopwatch();  
stopwatch.Start();  
//LOAD    
//Created a temporary dataset to hold the records    
List < Tuple < stringstringstring >> listA = new List < Tuple < stringstringstring >> ();  
using(var reader = new StreamReader(@ "C:\Users\Lenovo\Desktop\5m Sales Records.csv")) {  
    while (!reader.EndOfStream) {  
        var line = reader.ReadLine();  
        var values = line.Split(',');  
        listA.Add(new Tuple < stringstringstring > (values[0], values[1], values[11]));  
    }  
}  
//PROCESS    
var top10HigestRevenueSalesRecords = from salesrec in listA.Skip(0).Take(10)  
orderby salesrec.Item3  
select salesrec;  
//PRINT    
foreach(var item in top10HigestRevenueSalesRecords) {  
    Console.WriteLine($ "{item.Item1} - {item.Item2} - {item.Item3}");  
}  
stopwatch.Stop();  
Console.WriteLine($ "Time ellapsed {stopwatch.ElapsedMilliseconds/1000}");  
Console.ReadLine(); 

现在,在过程加载、过程和打印中的三个主要步骤都在2秒之内完成。

添加并行。对于这个场景,Foreach要么没有多大作用,事实上,它会使它慢一点,再差一点纳秒,这是不需要考虑的。

我们可以通过使用一些定制的Nuget包来进一步改进它,从而减少加载大型csv文件的停机时间。

using LumenWorks.Framework.IO.Csv;  
using(CsvReader csv = new CsvReader(new StreamReader(@ "C:\Users\Lenovo\Desktop\5m Sales Records.csv"), true)) {  
    while (csv.ReadNextRecord()) {  
        listA.Add(new Tuple < stringstringstring > (csv[0], csv[1], csv[11]));  
    }  
}   
ICP备案号:苏ICP备14035786号-1 苏公网安备 32050502001014号