日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

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

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

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

1.前言

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

2.示例

通過類型檢查的優化,優化掉某些情況下類型轉換的時候JIT類型檢查的函數。下面的代碼是類型檢查的典型應用。WHy28資訊網——每日最新資訊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執行即可WHy28資訊網——每日最新資訊28at.com

ldelem.ref

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

ldelema [System.Runtime]System.String

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

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

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

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

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

3.第一階優化

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

.Net7:WHy28資訊網——每日最新資訊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進行安全性檢查。WHy28資訊網——每日最新資訊28at.com

.Net8:WHy28資訊網——每日最新資訊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_REFWHy28資訊網——每日最新資訊28at.com

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

4.第二階優化

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

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

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

用以縮短CastHelpers.ChkCastAny的編譯時間,提高編譯的時間和程序的性能。WHy28資訊網——每日最新資訊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;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 临颍县| 玉溪市| 大埔县| 青川县| 太仓市| 宁乡县| 安庆市| 江都市| 武乡县| 辽源市| 南开区| 邻水| 颍上县| 商城县| 奎屯市| 揭西县| 平原县| 泽库县| 霍山县| 贵溪市| 大方县| 达尔| 抚州市| 北碚区| 阜康市| 沛县| 县级市| 怀安县| 双辽市| 凉山| 龙江县| 和龙市| 绍兴县| 龙海市| 阿拉善盟| 罗田县| 东阿县| 石景山区| 江华| 山东省| 万山特区|