为什么.NET Core 2.0的性能比.NET Framework 4.6.1差

时间:2018-03-22 09:50:32

标签: c# .net-core

我写了一个程序,创建了4个线程,每个线程从低到高排序20.000个数字50次。我在.NET Core 2.0和.NET Framework 4.6.1上多次运行此测试。在此测试中,.NET Framework总是优于.NET Core。

设置

  • .NET Core处于发布模式&公布
  • Windows 10,i7 duo core,4线程(超线程)

以下代码用于对两个框架进行基准测试。

static void Main()
    {
        const int amountParallel = 4;
        var globalStopwatch = new Stopwatch();

        globalStopwatch.Start();

        var tasks = new Task<double[]>[4];

        for (int i = 0; i < amountParallel; i++)
        {
            tasks[i] = Start();
        }

        Task.WaitAll(tasks);

        globalStopwatch.Stop();

        Console.WriteLine("Averages: {0}ms", tasks.SelectMany(r => r.Result).Average(x => x));
        Console.WriteLine("Time completed: {0}", globalStopwatch.Elapsed.TotalMilliseconds);
    }

    private static Task<double[]> Start()
    {
        return Task.Factory.StartNew(() =>
        {
            var numbersToSort = new int[20000];

            var globalStopwatch = new Stopwatch();
            var individualStopwatch = new Stopwatch();
            var stopwatchTimes = new double[50];
            int temp;

            globalStopwatch.Start();

            for (int i = 0; 50 > i; i++)
            {
                Console.WriteLine("Running task: {0}", i);
                numbersToSort = Enumerable.Range(0, 20000).Reverse().ToArray();
                individualStopwatch.Start();

                for (int indexNumberArray = 0; numbersToSort.Length > indexNumberArray; indexNumberArray++)
                {
                    for (int sort = 0; numbersToSort.Length - 1 > sort; sort++)
                    {
                        if (numbersToSort[sort] > numbersToSort[sort + 1])
                        {
                            temp = numbersToSort[sort + 1];
                            numbersToSort[sort + 1] = numbersToSort[sort];
                            numbersToSort[sort] = temp;
                        }
                    }
                }

                individualStopwatch.Stop();

                Console.WriteLine("Task {0} completed, took: {1}ms", i, Math.Round(individualStopwatch.Elapsed.TotalMilliseconds));

                stopwatchTimes[i] = individualStopwatch.Elapsed.TotalMilliseconds;

                individualStopwatch.Reset();
            }

            globalStopwatch.Stop();

            Console.WriteLine("Total time: {0}s", Math.Round(globalStopwatch.Elapsed.TotalSeconds, 2));
            Console.WriteLine("Average: {0}ms", Math.Round(stopwatchTimes.Average(time => time)));

            return stopwatchTimes;
        }, TaskCreationOptions.LongRunning);
    }

测试结果:

.NET Core

  • 平均值:761毫秒
  • 总时间:38秒

.NET Framework

  • 平均:638毫秒
  • 总时间:32秒

.NET Core在仅与CPU相关的任务上并不慢。它在磁盘I / O任务上也较慢。

任何想法为什么.NET Core在这方面有点慢?我可以做些改进来提高.NET Core的性能吗?

2 个答案:

答案 0 :(得分:11)

.NET Framework项目默认为32位代码。此选项在项目的构建设置中可见,默认情况下已选中。 .NET Core项目默认为64位代码。如果取消勾选“首选32位”框,您会注意到.NET Framework性能下降。

  

另一点值得注意的是桌面x86 JIT是一个单独的代码   来自x64 JIT。对于64位,.NET Framework和.NET Core   现在使用RyuJIT;对于32位.NET Core仍然使用RyuJIT,但.NET   Framework使用传统的JIT,因此你有不同的位数   和不同的抖动。

答案在Hans Passant和Jeroen Mostert的评论中提供。

答案 1 :(得分:9)

这应该通过https://github.com/dotnet/coreclr/pull/15323

在.Net Core 2.0.7和.Net Framework 4.7.2中修复

根本原因是JIT的Common Subexpression Elimination(又名CSE)优化中的一个错误。有关血腥的详细信息,请参阅问题(从PR链接)。