AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

.Net8頂級性能優化:類型轉換

來源: 責編: 時間:2023-11-06 17:19:51 330觀看
導讀1.前言.Net8通過各種騷操,把性能提升到了前所未有的高度。超越以往任何版本,也涵蓋了后續版本,比如.NET9或許可能沒有如此大的性能優化了。本篇來看下它其中的一個優化:類型轉換的優化效果。2.示例通過類型檢查的優化,優

1.前言

.Net8通過各種騷操,把性能提升到了前所未有的高度。超越以往任何版本,也涵蓋了后續版本,比如.NET9或許可能沒有如此大的性能優化了。本篇來看下它其中的一個優化:類型轉換的優化效果。qcY28資訊網——每日最新資訊28at.com

2.示例

通過類型檢查的優化,優化掉某些情況下類型轉換的時候JIT類型檢查的函數。下面的代碼是類型檢查的典型應用。qcY28資訊網——每日最新資訊28at.com

[HideColumns("Error", "StdDev", "Median", "RatioSD")][DisassemblyDiagnoser(maxDepth: 0)]public class Tests{  private readonly string[] _strings = new string[1];  [Benchmark]  public string Get1() => _strings[0];  [Benchmark]  public string Get2() => Volatile.Read(ref _strings[0]);}public partial class Program{   static void Main(string[] args)   {     BenchmarkSwitcher.FromAssembly(typeof(Tests).Assembly).Run(args);   }}

我們看到_strings是個私有數組,Get1函數中獲取_strings數組的第一個值。所以它是直接用ldelem.ref IL執行即可qcY28資訊網——每日最新資訊28at.com

ldelem.ref

但是Get2里面對數組元素進行了引用,所以Roslyn的指令是:qcY28資訊網——每日最新資訊28at.com

ldelema [System.Runtime]System.String

如果ref類型的變量,被賦值為不同于這個變量的類型則會違反類型安全性。通常情況下ldelema需要進行類型檢查,也就是用JIT輔助函數CORINFO_HELP_LDELEMA_REF來進行檢查,以確保不會違反類型安全性。qcY28資訊網——每日最新資訊28at.com

這個安全性的檢查會極大損耗性能,.NET8的JIT進行了一個優化,思路是如果是sealed關鍵字標記的類型,就不會進行安全性檢查,這樣就會提高性能。為什么sealed不會呢?qcY28資訊網——每日最新資訊28at.com

這其實是利用了它的一個特性,就是不會被繼承。不會被繼承,就不會被子類的類型所困擾,只有string一個類型,自然不會用以進行類型檢查了。qcY28資訊網——每日最新資訊28at.com

qcY28資訊網——每日最新資訊28at.com

這是第一點優化,下面看下。qcY28資訊網——每日最新資訊28at.com

3.第一階優化

優化了類型安全檢查,縮短了編譯時間,提高了性能。來看下.Net7和.NET8的生成Get2函數的的不同點qcY28資訊網——每日最新資訊28at.com

.Net7:qcY28資訊網——每日最新資訊28at.com

Tests.Get2()       sub       rsp,28       mov       rcx,[rcx+8]       xor       edx,edx       mov       r8,offset MT_System.String       call      CORINFO_HELP_LDELEMA_REF       mov       rax,[rax]       add       rsp,28       ret; Total bytes of code 33

.Net7它這里有一個CORINFO_HELP_LDELEMA_REF進行安全性檢查。qcY28資訊網——每日最新資訊28at.com

.Net8:qcY28資訊網——每日最新資訊28at.com

; Tests.Get2()       sub       rsp,28       mov       rax,[rcx+8]       cmp       dword ptr [rax+8],0       jbe       short M00_L00       mov       rax,[rax+10]       add       rsp,28       retM00_L00:       call      CORINFO_HELP_RNGCHKFAIL       int       3; Total bytes of code 29

.Net8里它沒有了CORINFO_HELP_LDELEMA_REFqcY28資訊網——每日最新資訊28at.com

因為string類型是sealed,它的原型如下:qcY28資訊網——每日最新資訊28at.com

public sealed class String : IEnumerable<char>, IEnumerable, ICloneable, IComparable, IComparable<String?>, IConvertible, IEquatable<String?>{  //這里代碼省略}

JIT會判斷類型是否是sealed標志,如果是則不進行安全性檢查優化。qcY28資訊網——每日最新資訊28at.com

雖然.Net8去掉了CORINFO_HELP_LDELEMA_REF,qcY28資訊網——每日最新資訊28at.com

但是多了范圍的檢查CORINFO_HELP_RNGCHKFAIL,那它這個性能如何呢?qcY28資訊網——每日最新資訊28at.com

我們來測試下:qcY28資訊網——每日最新資訊28at.com

dotnet run -c Release -f net7.0 --filter "*" --runtimes net7.0 net8.0

結果是:qcY28資訊網——每日最新資訊28at.com

Method
qcY28資訊網——每日最新資訊28at.com

RuntimeqcY28資訊網——每日最新資訊28at.com

Mean
qcY28資訊網——每日最新資訊28at.com

Ratio
qcY28資訊網——每日最新資訊28at.com

Code Size
qcY28資訊網——每日最新資訊28at.com

Get2qcY28資訊網——每日最新資訊28at.com

.NET 7.0qcY28資訊網——每日最新資訊28at.com

1.0537 nsqcY28資訊網——每日最新資訊28at.com

1.00qcY28資訊網——每日最新資訊28at.com

33 BqcY28資訊網——每日最新資訊28at.com

Get2qcY28資訊網——每日最新資訊28at.com

.NET 8.0qcY28資訊網——每日最新資訊28at.com

0.2423 nsqcY28資訊網——每日最新資訊28at.com

0.23qcY28資訊網——每日最新資訊28at.com

29 BqcY28資訊網——每日最新資訊28at.com

我們看到同樣代碼,.Net8里面比.Net7的性能提升了5倍之多。qcY28資訊網——每日最新資訊28at.com

4.第二階優化

承接上面,上面sealed去掉了類型檢查。qcY28資訊網——每日最新資訊28at.com

然后在類型轉換的時候,一般的類型轉換JIT使用的是CastHelpers.ChkCastAny來進行。qcY28資訊網——每日最新資訊28at.com

但是.Net8里面內聯了一個方法qcY28資訊網——每日最新資訊28at.com

用以縮短CastHelpers.ChkCastAny的編譯時間,提高編譯的時間和程序的性能。qcY28資訊網——每日最新資訊28at.com

using BenchmarkDotNet.Attributes;using BenchmarkDotNet.Running;using System.Runtime.CompilerServices;BenchmarkSwitcher.FromAssembly(typeof(Tests).Assembly).Run(args);[HideColumns("Error", "StdDev", "Median", "RatioSD")]public class Tests{    private readonly object _o = "hello";    [Benchmark]    public string GetString() => Cast<string>(_o);    [MethodImpl(MethodImplOptions.NoInlining)]    public T Cast<T>(object o) => (T)o;}

同樣的qcY28資訊網——每日最新資訊28at.com

dotnet run -c Release -f net7.0 --filter "*" --runtimes net7.0 net8.0

結果如下:qcY28資訊網——每日最新資訊28at.com

Method
qcY28資訊網——每日最新資訊28at.com

Runtime
qcY28資訊網——每日最新資訊28at.com

Mean
qcY28資訊網——每日最新資訊28at.com

Ratio
qcY28資訊網——每日最新資訊28at.com

GetStringqcY28資訊網——每日最新資訊28at.com

.NET 7.0qcY28資訊網——每日最新資訊28at.com

3.018 nsqcY28資訊網——每日最新資訊28at.com

1.00qcY28資訊網——每日最新資訊28at.com

GetStringqcY28資訊網——每日最新資訊28at.com

.NET 8.0qcY28資訊網——每日最新資訊28at.com

1.198 nsqcY28資訊網——每日最新資訊28at.com

0.40qcY28資訊網——每日最新資訊28at.com

.Net8是三倍于.Net7的運行速度。去掉類型檢查+類型轉換的內聯,大幅度的提升效率,可見.Net8的性能優化確實不容小覷。qcY28資訊網——每日最新資訊28at.com

參考如下:qcY28資訊網——每日最新資訊28at.com

https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/

最后推薦下個人的CLR/JIT交流圈,里面有多篇個人編寫的高質量的原創欄目和文章。學習心得,項目經驗等。帶你進入.Net核心技術階層,脫離curd工程師范疇。qcY28資訊網——每日最新資訊28at.com

qcY28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-17278-0.html.Net8頂級性能優化:類型轉換

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Go 與數據可視化:使用 Gonum 和 Plot 庫探索數據之美

下一篇: 攜程后臺低代碼平臺的探究與實踐

標簽:
  • 熱門焦點
Top