同步原语也在.NET Core中得到提升。例如,低级并发代码通常使用SpinLock来尝试避免分配锁定对象或最小化竞争锁所花费的时间。PR dotnet / coreclr#6952改进了失败的快速路径,以下测试会得到显而易见的结果:
using System; using System.Diagnostics; using System.Threading; class Test { static void Main() { while (true) { bool taken = false; var sl = new SpinLock(false); sl.Enter(ref taken); var sw = Stopwatch.StartNew(); for (int i = 0; i < 100_000_000; i++) { taken = false; sl.TryEnter(0, ref taken); } Console.WriteLine(sw.Elapsed); } } }
在.NET 4.7中,会得到如下结果:
::00:02.2974777
而在.NET Core 2.0中,会得到如下结果:
::00:00.3886977
吞吐量的这种差异可能会对运行这种锁的热路径产生很大的影响。
这只是众多例子中的一个。另一个例子围绕着Lazy<T>,它被PR dotnet / coreclr#8963用manofstick重写,以便提高访问初始化过的Lazy <T>的效率。这样的提升效果从下面的示例中清晰可见:
using System; using System.Diagnostics; class Test { static int s_result; static void Main() { while (true) { var lazy = new Lazy<int>(() => 42); s_result = lazy.Value; var sw = Stopwatch.StartNew(); for (int i = 0; i < 1_000_000_000; i++) { s_result = lazy.Value; } Console.WriteLine(sw.Elapsed); } } }
在.NET 4.7中,会得到的结果如下:
::00:02.7253927
而在.NET Core 2.0中,会得到的结果如下:
::00:00.5502970
吞吐量增加约5倍。
下一步是什么
本文只涉及了部分.NET Core的性能改进。在dotnet / corefx和dotnet / coreclr repos 中的pull请求中搜索“perf”或“performance”,你会发现接近一千个合并的PR改进。其中一些是比较大的同时也很有影响力的改进,而另一些则主要减少了库和运行时的消耗,这些变化一起起作用,保证了能够在.NET Core上更快的运行应用程序。展望未来,性能将成为关注的重点,无论是以性能改进为目标的API还是现有库的性能的改进。
欢迎大家深入了解.NET Core代码库,以便找到影响自己的应用程序和库的瓶颈,并提交PR来修复它们。如果你的问题得到修复,也请将修复程序分享给所有需要的人。
转载请注明出自:葡萄城控件
相关阅读:
【报表福利大放送】100余套报表模板免费下载
Visual Studio 2017正式版发布全纪录
从Visual Studio看微软20年技术变迁
Visual Studio 20周年,我和VS不得不说的故事