背景
我们目前正在将代码库从 .Net Framework 4.8 转换为 .Net Core 3.1。
其中一些代码非常注重性能。一个例子是应用 Hamming 窗口滤波器的某些代码;我有点失望地发现,与为 .Net Framework 4.8 编译的相同代码相比,为 .Net Core 3.1 编译的代码运行速度慢了约30%。
如何重现
我创建了一个多目标 SDK 样式的项目,步骤如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworkS>net48;netcoreapp3.1</TargetFrameworkS>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
</Project>
这个项目的代码如下(重要的代码在
for (int iter = ...
循环内部):using System;
using System.Diagnostics;
namespace FooBar
{
class Program
{
static void Main()
{
#if NET48
Console.WriteLine("NET48: Is 64 bits = " + Environment.Is64BitProcess);
#elif NETCOREAPP3_1
Console.WriteLine("NETCOREAPP3_1: Is 64 bits = " + Environment.Is64BitProcess);
#else
Invalid build, so refuse to compile.
#endif
double[] array = new double[100_000_000];
var sw = Stopwatch.StartNew();
for (int trial = 0; trial < 100; ++trial)
{
sum(array);
}
Console.WriteLine("Average ms for calls to sum() = " + sw.ElapsedMilliseconds/100);
Console.ReadLine();
}
static double sum(double[] array)
{
double s = 0;
for (int i = 0; i < array.Length; ++i)
{
s += array[i];
}
return s;
}
}
}
结果
我测试了.Net Core 3.1和.Net Framework 4.8的x86版本,并计时发布,得到如下结果:
.Net Core 3.1:
NETCOREAPP3_1: Is 64 bits = False
Average ms for calls to sum() = 122
.Net Framework 4.8:
NET48: Is 64 bits = False
Average ms for calls to sum() = 96
因此,.Net Core 3.1 的结果比 .Net Framework 4.8 慢约30%。
注意:这只影响x86版本的构建。对于x64版本,.Net Framework和.Net Core之间的时间差异不大。
我认为这非常令人失望,特别是因为我认为 .Net Core 可能具有更好的优化...
有人能建议一种方法来加速 .Net Core 输出,使其与 .Net Framework 4.8 处于同一水平吗?
编辑:我已更新代码和 .csproj 到最新版本以进行测试。 我添加了一些代码来指示正在运行哪个目标和平台,以确保运行正确的版本。
通过这次编辑,基本上只是在计时一个包含100,000,000个元素的大 double[] 数组的总和所需的时间。
我可以在我的两台PC和笔记本电脑上复制这个问题,它们都运行着最新的Windows 10和Visual Studio 2019安装程序+最新的 .Net Core 3.1。
然而,考虑到其他人无法复制这个问题,我将采纳Lex Li的建议,并将此贴到Microsoft的Github页面上。