与 .Net Framework 相比,.Net Core 中的代码运行速度慢 30% - 有什么方法可以加快速度吗?

Mat*_*son 8 c# performance .net-core-3.1 .net-framework-4.8

背景

我们目前正在将我们的代码库从 .Net Framework 4.8 转换为 .Net Core 3.1。

一些代码对性能非常敏感。一个例子是一些应用汉明窗口过滤器的代码;我有点沮丧地发现 .Net Core 3.1 编译的代码比为 .Net Framework 4.8 编译的相同代码的运行速度慢了大约 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>
Run Code Online (Sandbox Code Playgroud)

本项目代码如下(重要代码在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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果

为 .Net Core 3.1 和 .Net Framework 4.8定时发布x86 版本,我得到以下结果:

.Net 核心 3.1:

NETCOREAPP3_1: Is 64 bits = False
Average ms for calls to sum() = 122
Run Code Online (Sandbox Code Playgroud)

.Net 框架 4.8:

NET48: Is 64 bits = False
Average ms for calls to sum() = 96
Run Code Online (Sandbox Code Playgroud)

因此,.Net Core 3.1 的结果比 .Net Framework 4.8 慢 30% 左右。

注意:这仅影响 x86 构建。对于 x64 构建,.Net Framework 和 .Net Core 之间的时间相似。

我觉得这最令人失望,特别是因为我认为 .Net Core 可能会有更好的优化......

任何人都可以建议一种方法来加速 .Net Core 输出,使其与 .Net Framework 4.8 处于同一范围内吗?


[编辑] 我已将代码和 .csproj 更新为我用于测试的最新版本。我添加了一些代码来指示正在运行的目标和平台,只是为了确定正在运行正确的版本。

通过此编辑,我基本上只是计算将大型 double[] 数组的所有 100,000,000 个元素相加所需的时间。

我可以在运行最新 Windows 10 和 Visual Studio 2019 安装 + 最新 .Net Core 3.1 的 PC 和笔记本电脑上重现这一点。

但是,鉴于其他人无法重现这一点,我将采纳 Lex Li 的建议并将其发布到 Microsoft github 页面上。

Bli*_*ndy 0

好吧,我尝试了一下,我也包含了 .Net5,正如预期的那样,它们的性能几乎相同。

我将此视为使用更严格的测试方法 (Benchmark.NET) 的标志,因为此时我确信您没有运行正确的可执行文件,而 Benchmark.NET 会为您解决这个问题。

C:\Users\_\source\repos\ConsoleApp3\ConsoleApp3\bin\Release\net48>ConsoleApp3.exe
Computed 4199.58 in 00:00:01.0134120
Computed 4199.58 in 00:00:01.0136130
Computed 4199.58 in 00:00:01.0163664
Computed 4199.58 in 00:00:01.0161655

C:\Users\_\source\repos\ConsoleApp3\ConsoleApp3\bin\Release\net5>ConsoleApp3
Computed 4199.580000000003 in 00:00:01.0269673
Computed 4199.580000000003 in 00:00:01.0214385
Computed 4199.580000000003 in 00:00:01.0295102
Computed 4199.580000000003 in 00:00:01.0241006

C:\Users\_\source\repos\ConsoleApp3\ConsoleApp3\bin\Release\netcoreapp3.1>ConsoleApp3
Computed 4199.580000000003 in 00:00:01.0234075
Computed 4199.580000000003 in 00:00:01.0216327
Computed 4199.580000000003 in 00:00:01.0227448
Computed 4199.580000000003 in 00:00:01.0328213
Run Code Online (Sandbox Code Playgroud)

  • 在使用 .Net 的 32 位环境中,您会遇到很多问题,它通常被视为非平台。许多主要优化仅适用于 64 位,以及前面提到的高效 GC 模型。请随意在 .Net JIT 存储库中发布您的问题,但如果您无法使用 64 位运行时,请不要指望奇迹。 (2认同)