我们有一个场景,需要使用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 < string, string, string >> listA = new List < Tuple < string, string, string >> ();
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 < string, string, string > (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 < string, string, string > (csv[0], csv[1], csv[11]));
}
}