我有一个.NET Core类库(我们称它为Core),我想使用WPF GUI来使用它的某些功能。但是,与.NET Core相比,.NET似乎非常慢。例如,我有以下要运行的方法:
private static void LoadData()
{
Stopwatch w = new Stopwatch();
List<BookingRecord> records = new List<BookingRecord>();
w.Start();
string csv = File.ReadAllText("/BookingData/Booking_Data - Copy.csv");
Console.WriteLine(w.Elapsed);
w.Restart();
var lines = csv.Split('\n');
foreach(var line in lines.Skip(1))
{
var data = line.Split(';');
records.Add(new BookingRecord()
{
Origin = data[2],
Destination = data[3],
FlightDate = DateTime.Parse(data[4], new CultureInfo("De-de").DateTimeFormat),
PassengersNumber = int.Parse(data[9])
});
}
Console.WriteLine(w.Elapsed);
w.Stop();
}
为此,我使用了两个控制台应用程序,一个在.NET Core下,一个在.NET Framework下。在.NET Core下构造BookingData
列表的时间为0.4s
,而在.NET Framework中,情况为10s
左右,这是有问题的,因为我将加载大约2的较大文件百万行及以上(客户要求)。
那么这个问题有什么解决方法吗?目的是提供一个显示Core库结果的GUI。
EDIT
上面的代码片段只是为了提供MCVE,否则,我将在StreamReader
的帮助下使用CsvHelper
来读取文件,并且在读取时就完成了构造。
编辑2
数据的加载和构建是在Core库内部进行的,换句话说,通常使用.NET Core,WPF或.NET Framework项目,它只是引用Core库并使用其方法,它只是一个显示工具。为什么它必须产生与将代码移至.NET项目时相同的结果?
答案 0 :(得分:1)
MS表示您应该使用.Net Core的主要原因之一是性能提升。 Google搜索似乎可以验证这一点。
但是,如果您每次使用某种缓冲读取器一次读取文件,则无论使用哪种平台,都可能会看到更好的性能,以及绝对更好的内存利用率。使用ReadAllText将尝试一次将所有200万行加载到内存中。如果您要做的只是按照它们在文件中出现的顺序处理每一行,则没有必要。
答案 1 :(得分:1)
阅读以下各行后,尝试移动列表创建:
var lines = csv.Split('\n');
var records = new List<BookingRecord>(lines.Length);
这将产生巨大的差异。在您的版本中,它将以8个项目的基础数组开始,当完整时创建16个项目中的一个并复制旧项,当完整时,创建32个项目中的基础数组并复制16个,依此类推
将其初始化为正确的大小可以防止这种情况。也许Core已经能够以更智能的方式做到这一点。尽管25倍的因子似乎表明这里还有其他事情在起作用,但它应该会显着提高。
如果将记录设为结构而不是类,则速度会更快,因为它可以一次性保留整个内存块,而不是每条记录只保留一小部分。