.NET 5 是. NET 繼 Core 之後要推出的下一代的版本,自從微軟推出 .NET Core 平台之後也過了三代,.NET5 由 Core3 改良,並支援 WPF 和 Win Forms 開發,納入了 C#9 和 F#5、未來的 Xamarin 和 .NET Web Assembly 也預定將函式庫轉移為 .NET 5。在撰寫此文的當下,微軟官方釋出最新的版本為 v5.0.0-preview.4,若想使用 .NET 5,Visual Studio 2019 必須升級到 16.6 上(Mac 尚未支援);若使用 Visual Studio Code 則需下載最新的 C# Extenstion。
我們的許多專案例如簡訊、行動網頁或是工具類型的函式庫都是分別使用.NET Framework、.NET Core、.NET Standard開發,而微軟此次發布 .NET5 的目標之一便是簡化目標框架版本的分歧。例如前一段時間 .NET Core 和 NET Standard 並行,在填寫 SDK 版本時需選擇例如 netcoreapp3.1 and netstandard2.0。從 .NET5 之後預計再度併回同一版本線,例如 net5.0, net6.0,因此不再需要跨產品兼容的 .NET Standard;另外新增了一些 Target Framework Moniker 的擴充及 SDK 刪減,使得 .NET5.0 能夠使用跨平台 API,而非只限於 Standarad 中的內容。
圖一、.NET Roadmap 來源:官方 Github
.NET5 有許多更動,以下挑幾點條列:
- 效能的改善,包括:正規表達式、string 和 char 部份方法的改良、Http 1.1/2 的效能增進、分層編譯改進、利用 xmm 暫存器清除 stack prolog 以加快效能……等等,更詳細的內容可以查閱 Github 上的 PR 項目。
- 編譯有分為即時性和階層式編譯,在 .NET Core 3.0 或更新版本中,編譯預設為階層式編譯,在這次釋出的版本中對階層式編譯做了兩項重大的改良。在分層編譯中,Call-counting 機制扮演重要的角色,一旦一個方法被多次調用,Runtime 就會要求 JIT 嘗試用更好的方式去重新編譯。然而過去從效能分析的結果中,我們能觀察到 Call-counting 的速度拖慢了整體的表現,在此次 .NET5 的新釋出版本終於改善了這部分的問題,也增進了分層式編譯的效能。另一個改善點是關於包含迴圈的方法在分層式編譯中的表現,例如一個很少呼叫的方法,卻被放在遞迴一百萬次迴圈中--這當然是較為極端的例子,最常見的典型就是Main。官方為了解決此問題,讓分層預設避開含有迴圈的方法,並使應用程式可以選擇是否要對這類方法套用分層編譯。此外還實作了類似 Java VM 中的功能 On-stack replacement(OSR),允許程式執行時對程式碼進行更動並重新編譯。
- 採用 Pinned Object Heap 以減少 Heap Fragmentation
- 單一檔案應用程式(Single file applications):一種新的單一檔發布種類,可經由單一 Binaary File 執行應用程式。此功能的建構有兩個難點--其一是 Linux 和 Windows 的功能和限制不同,在進行發布時擁有的本機資源不一樣;其二是要確保 debugger 可以為單一檔案類型的應用程式提供和多檔類型一致的使用體驗。這兩點使得此功能的建構成本提高,有興趣的讀者可以參考官方在 Github 上的 Issue #36590: Support Single-File Apps in .NET 5。
JSON APIs:簡化了從 Newtonsoft.Json 搬遷至 System.Text.Json 的複雜度。System.Text.Json 是 .NET Core3.0 ore3.0 之後新增的函式庫,效能大幅改進,有望取代過去多年一直是 Json 函式庫首選的 Newtonsoft.Json。官方提供了搬遷指南Migrate from Newtonsoft.Json to System.Text.Json – .NET,但有些程式碼仍舊無法完整搬遷至新的函式庫,此方面的障礙仍須花費時間改良。
Reference
https://github.com/dotnet/runtime/blob/master/docs/design/features/OnStackReplacement.md
https://dotnet.microsoft.com/download/dotnet/5.0
https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0-known-issues.md
https://github.com/dotnet/runtime/pulls?page=2&q=is%3Apr+is%3Aclosed+label%3Atenet-performance
https://devblogs.microsoft.com/dotnet/announcing-net-5-preview-4-and-our-journey-to-one-net/