我们有一个场景,需要使用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; | |
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])); | |
} | |
} |