|
前言 2021 年 2 月 17 日微軟發(fā)布了 .NET 6 的 Preview 1 版本,那么來看看都有什么新特性和改進吧,由于內容太多了因此只介紹一些較為重點的項目。ASP.NET Core 6 Preview 1 和 EF Core 6 Preview 1 同樣有很多的更新內容,但是限于篇幅就不在這里介紹了。
統(tǒng)一和擴展 .NET 6 在 .NET 5 的統(tǒng)一的基礎之上,繼續(xù)借助 Xamarin 擴展到 Android、iOS 和 macOS。此外,.NET 6 還擴展了 Blazor 的適用范圍,開發(fā)者可以通過 Blazor Hybrid 開發(fā)混合的跨平臺客戶端應用。 對于 Andriod、iOS 和 WebAssembly 將使用 mono 作為 runtime,但是基礎庫將全面與 .NET 統(tǒng)一。 安裝了 .NET 6 的 SDK 之后,將能構建移動平臺應用,例如對于安卓來說,運行 dotnet new andriod 就能創(chuàng)建一個安卓應用的項目,然后運行 dotnet run 便能直接啟動安卓模擬器運行。 另外,為了統(tǒng)一、簡化并擴展構建 Xamarin.Forms 應用,也將推出 MAUI 提供諸多改進和功能,允許開發(fā)者直接使用 .NET 開發(fā)桌面和移動客戶端程序。 主題 微軟利用 Blazor Server 開發(fā)了 themesof.net 用于展示和跟蹤主題,用戶可以通過查看該網(wǎng)站中列出的各項目內容來跟蹤 .NET 目前的狀態(tài)和未來的發(fā)展計劃。 平臺支持 .NET 6 LTS 將在 2021 年 11 月正式發(fā)布,除了目前支持的平臺之外,還將支持以下平臺:
MAUI .NET MAUI (Multi-platform App UI) 是一組現(xiàn)代 UI 框架,在 Xamarin.Forms 的基礎上擴展并集成到 .NET 6 中,利用 MAUI 將能夠面向 Android、iOS、macOS 和 Windows 等構建應用。 在統(tǒng)一的過程中,將會把 Xamarin.Essentials 庫集成到 MAUI 當中,除此之外你將還能容易地利用設備機能,例如傳感器、照片庫、聯(lián)系人和存儲等等。 .NET 6 Preview 1 中首先包含了 Android 和 iOS 兩個平臺的 MAUI,可以在此處查看示例項目和安裝說明:https://github.com/dotnet/net6-mobile-samples。 未來還將添加 macOS 和 Windows 桌面支持,以及除了 XAML 熱重載之外,還將支持 C# 代碼的熱重載。 對于今天已經(jīng)在使用 Xamarin 構建應用的開發(fā)者,將會提供轉換工具和遷移指導幫助遷移到 .NET 6,
上圖中,Android 和 iOS 應用直接通過 dotnet 的命令從命令行中啟動,分別運行在模擬器中,代碼利用了 dotnet-runtimeinfo 在控制臺中輸出了運行時的信息:應用是利用 .NET 的 SDK 開發(fā),在 mono 的運行時之上使用 .NET 的類庫。 Blazor 桌面應用 Blazor Desktop 將允許開發(fā)者利用 Blazor 技術開發(fā)混合客戶端程序,將原生 UI 和 Web 技術混合起來構建原生的客戶端應用。 例如你可以直接將 Blazor 作為組件集成到現(xiàn)有的 WPF 應用當中,下面是幾個例子: 在 macOS 運行的 Blazor 桌面客戶端應用:
在 WPF 中集成 Blazor 的混合應用:
快速內部循環(huán) 快速迭代開發(fā)是任何高效且令人愉悅的平臺的標志,為此微軟啟動了一個新項目:快速內部循環(huán)(fast inner loop)。該項目旨在讓應用的構建速度大幅度提高,并提供在運行時修改代碼無需重新編譯和重啟應用,直接熱重載代碼并應用的功能。 幾年來 .NET 一直具有 XAML 熱重載功能,這一次,熱重載功能將不僅局限于 XAML,而是擴展到 C# 和 IL。微軟將定義代碼熱重載模型以讓該功能支持所有類型的 app,這其中的一些功能需要通過改進運行時來做到,屆時 CoreCLR 和 Mono 將一起受益。 最終通過該項目,開發(fā)者將能夠非??斓臉嫿椖?,并且在調試運行時直接跳過編譯,通過熱重載功能完成代碼的修改,而無需重新啟動。 ARM64 .NET 將持續(xù)改進 ARM64 的支持。 ARM64 的性能改進計劃 .NET 將持續(xù)改善在 ARM64 架構上的性能表現(xiàn),具體可以去這里查看 .NET 6 在此方面的計劃:https://github.com/dotnet/runtime/issues/43629 WPF 支持 WPF 現(xiàn)在支持 Windows ARM64 了,如需反饋相關問題可以前去:https://github.com/dotnet/wpf/issues/4117
macOS ARM64 支持 .NET 5 將提供對 macOS ARM64 的 x86_64 模擬器支持,而 .NET 6 將提供對 macOS ARM64 的原生支持,下圖中展示了在 macOS 原生運行 ARM64 的 .NET:
容器 容器是 .NET 團隊的日常工作,既是構建基礎結構的基礎,又是產(chǎn)品方案,.NET 性能測試也在容器中完成。 在 .NET 6 中將針對如下項目改進容器支持:
除了第一條之外,上述所有特性都依賴 crossgen2 完成。雖然很多特性和容器沒太多關系,但是 .NET 將會在容器中使用他們。 在某些情況下,例如版本氣泡,容器可能是唯一默認啟用功能的分發(fā)工具。 容器的一個重要優(yōu)點是,與更通用的 .tar.gz,.deb 或 .msi 交付方式相比,可以以更“自以為是”的配置提供 .NET,例如提供性能更高配置的容器,但可能無法在所有情況下都可用(例如在舊硬件上)。 .NET 6 鏡像將分別在 Alpine 3.13(或更高)、Debian 11(bullseye)和 Ubuntu 20.04 上構建。 主題:PGO - 利用運行時信息提升啟動速度和吞吐量性能 本次來介紹一下 PGO 這個主題,后續(xù)每個 Preview 都將會介紹一些主題。 PGO(Profile-Guided Optimization) 的目標是優(yōu)化二進制內的原生代碼,讓其在 CPU 和其他方面的計算機上執(zhí)行的效率更高。優(yōu)化代碼可以讓程序速度更快,并能減少內存使用和硬盤使用?,F(xiàn)在微軟已經(jīng)在 native runtime 上面使用了 PGO,這是由在 Windows、macOS 和 Linux 上使用的 C++ 編譯器提供,雖然這部分內容很相關并重要,但是并不是這里的 PGO 所說的東西。 這里的 PGO 是指優(yōu)化 RyuJIT(.NET 的 JIT)產(chǎn)生的本機代碼。Crossgen 和 RyuJIT 已經(jīng)支持了 PGO,但是在 .NET 6 中將在可用度和性能上大幅改善該特性。 其中一個 PGO 技術是冷熱分離:將最常調用的代碼放在一起(熱),不常調用的代碼放到另一邊(冷)。理性情況下,由于已處于從磁盤加載的頁面的相同物理順序中,接下來一連串的方法調用或者基本塊訪問需要的代碼已經(jīng)被載入到了 CPU 的緩存中。這種情況下方法或者塊的調用將非???。除了上述的冷熱之外,還引入了 “非常冷” 這一組,這一組代碼將不會預編譯任何的原生代碼,只會在需要的時候被 JIT 編譯,這么做將能在不犧牲主要性能的情況下減小程序體積。 PGO 這項技術雖然不僅僅只在 .NET 中有所應用,但是該項技術非常不流行,因為做起來非常有難度,而且這類工具通常很笨重,并且在處理過程中需要非常注意細節(jié):開發(fā)者必須定期進行“訓練”,在此過程中,需要在各種情況下運行程序,同時工具會收集程序的運行數(shù)據(jù),然后把這些數(shù)據(jù)提供給編譯器,編譯器根據(jù)這些數(shù)據(jù)改善編譯結果,開發(fā)者接著去驗證結果。這一系列的過程非常麻煩且令人沮喪。 在 .NET 6 中,將計劃做以下 PGO 相關的支持:
PGO 將期望能得到 10% 的啟動速度提升和吞吐量性能提升,對于計算不敏感的工作負載,提升將更為顯著。 .NET 期望用兩個大版本的時間完成此方面完整的企劃。 TargetFramework 完整的 .NET TFM 將包含如下:
通過類似 <TargetFramework>net6.0</TargetFramework> 的方式可以適配到不同的平臺上。 命令行 在 .NET 6 中,對 CLI 也有不少改進。 響應文件 命令行支持響應文件,通過響應文件可以繞過控制臺對于字符數(shù)量的限制,同時也能減少用戶反復輸入相同命令的麻煩。 響應文件的支持已經(jīng)被添加到 .NET CLI 中,語法是 @file.rsp。而該文件本身就是簡單的一行文本,會在命令行中被結構化,例如下圖使用響應文件進行 dotnet build:
新指令 添加了兩個新的指令:
庫 .NET 6 Preview 1 的類庫新增了一些 API。 System.Numerics 的新數(shù)學 API
Windows 訪問控制列表的支持改進 用于操作 Windows ACLs 的包System.Threading.AccessControl 已經(jīng)被改進,為 EventWaitHandle, Mutex 和 Semaphore 加入了新的 OpenExisting 和 TryOpenExisting 方法,允許打開現(xiàn)有的通過特殊 Windows 安全描述符創(chuàng)建的線程同步對象。 運行時 .NET 6 Preview 1 的新運行時特性包含 Apple Silicon 支持、crossgen2 以及部分 PGO 改進等等。 可移植線程池 .NET 6 通過托管實現(xiàn),重新實現(xiàn)了 .NET 的線程池,并且作為 .NET 默認的線程池。 該線程池可以在不同平臺(CoreCLR、Mono 等)上提供相同的行為。 如果想要恢復以前用非托管代碼實現(xiàn)的線程池,可以指定環(huán)境變量 COMPlus_ThreadPool_UsePortableThreadPool=0,不過后續(xù)原來的線程池實現(xiàn)可能會被移除。 Apple Silicon 支持 .NET 6 Preview 1 開始原生支持 Apple Silicon,但是目前還處于 alpha 狀態(tài)。 對于 .NET 6,將同時支持 macOS ARM64 的原生運行以及通過羅塞塔 2 模擬運行 x64 版本的 .NET。 下面是同一臺 macOS ARM64 機器上運行 .NET 5 和 .NET 6 的輸出,你可以看到區(qū)別: Copy rich@MacBook-Air dotnet-runtimeinfo % pwd /Users/rich/git/core/samples/dotnet-runtimeinfo rich@MacBook-Air dotnet-runtimeinfo % dotnet run **.NET information Version: 5.0.3 FrameworkDescription: .NET 5.0.3 Libraries version: 5.0.3 Libraries hash: c636bbdc8a2d393d07c0e9407a4f8923ba1a21cb **Environment information OSDescription: Darwin 20.4.0 Darwin Kernel Version 20.4.0: Fri Jan 22 03:28:00 PST 2021; root:xnu-7195.100.296.111.3~3/RELEASE_ARM64_T8101 OSVersion: Unix 11.0.0 OSArchitecture: X64 ProcessorCount: 8 rich@MacBook-Air dotnet-runtimeinfo % export DOTNET_ROLL_FORWARD=Major rich@MacBook-Air dotnet-runtimeinfo % export DOTNET_ROLL_TO_PRERELEASE=1 rich@MacBook-Air dotnet-runtimeinfo % dotnet run **.NET information Version: 6.0.0 FrameworkDescription: .NET 6.0.0-preview.1.21102.12 Libraries version: 6.0.0-preview.1.21102.12 Libraries hash: 9b2776d48183632662e0be873cef029cdb57f8d6 **Environment information OSDescription: Darwin 20.4.0 Darwin Kernel Version 20.4.0: Fri Jan 22 03:28:00 PST 2021; root:xnu-7195.100.296.111.3~3/RELEASE_ARM64_T8101 OSVersion: Unix 11.3.0 OSArchitecture: Arm64 ProcessorCount: 8 Apple Silicon 原生支持 蘋果的新芯片相對于其他 ARM64 芯片來說有更嚴格運行要求,其中包括對 JIT 的要求,.NET 6 Preview 1 已經(jīng)滿足這些要求。 通用二進制(Universal binaries)是發(fā)布到蘋果商店的另一個新要求,但是目前 .NET 6 應用并不支持,因此不能發(fā)布到蘋果的應用商店,不過這部分也不是大部分 .NET 開發(fā)者所需要的。如果需要的話,.NET 會在 .NET 7 重新考慮是否支持通用二進制。 為了支持 Apple Silicon ABI 的要求,.NET 已經(jīng)做出了一些改進,下面是對應的 Pull Request:
調試 目前還無法在 Apple Silicon 上面調試原生 ARM64 的 .NET 程序,這將會在 Preview 3 或之后提供支持。不過通過羅塞塔 2 模擬運行 x64 的運行時是支持調試的。 已知問題
羅塞塔 2 仿真 .NET 5 的 x64 版本目前已經(jīng)支持通過羅塞塔 2 仿真運行在 macOS ARM64 上。 單文件應用 在 .NET 6,完成了用于 Windows 和 macOS 的完全單文件應用支持。此前這一項只支持 Linux,所以在其他平臺即使利用 PublishSingleFile 也還會帶幾個 .NET 的 dll 或者 dylib 文件。.NET 6 開始,這些文件都將被靜態(tài)鏈接到程序當中,變成真正的單文件。 當然,這只是對于 runtime 而言的,如果你的程序引用了其他的 native 庫,那么這些庫還是會外帶,而不會被鏈接進去。 macOS 單文件應用簽名 .NET 6 的單文件應用現(xiàn)在滿足了蘋果的公證和簽名要求,相關改動可以參考:https://github.com/dotnet/runtime/issues/3671。 Crossgen2 Crossgen2 將代替原有的 crossgen,旨在帶來如下優(yōu)點:
目前 .NET 的核心庫 System.Private.Corelib 本身已經(jīng)使用了 crossgen2 進行預編譯了,后面將會把整個 .NET 自身利用 crossgen2 進行預編譯。 這個項目并不是為了改進性能的,而是為托管 RyuJIT 提供更好的體系結構,在不需要或者不啟動運行時的情況下以“離線”方式生成代碼,以便更好地支持交叉編譯。 動態(tài) PGO 動態(tài) PGO是 .NET 正在探索和啟用的PGO模式之一。一方面,可以將其視為“無需訓練” 的 PGO。在文章的前面,我描述了 PGO 的使用過程,而動態(tài)PGO的優(yōu)點是不需要任何這些,但是缺點是過程需要更長的時間才能達到最佳性能。 另一方面,動態(tài) PGO 可以被認為是當今分層編譯所使用的更為簡單(且效果較差)的策略的替代品。 最引人注目案例中,動態(tài) PGO 和靜態(tài) PGO 組合到了一起。在運行時, JIT 可以細化一小部分經(jīng)過靜態(tài)編譯的 PGO 優(yōu)化代碼,以提供最大的好處。 例如,JIT 可以注意到,在到目前為止已加載的過程中,只有一個類實現(xiàn)了給定的接口,然后,JIT 可以生成通過類直接調用的代碼,而不是通過接口間接調用。 這種經(jīng)典的編譯器技術稱為去虛擬化,它通過消除方法調用中的間接操作并啟用內聯(lián)來提高性能。 作為啟用動態(tài) PGO 的一部分,.NET 已經(jīng)做出了如下改動:
ARM64 性能 Preview 1 中包含了以下改進:
上圖展示了改進帶來的影響,數(shù)值越低越好。綠色線是改進之后的,橘色是另一個實驗性改進的,藍色是原來的。 硬件加速的 struct struct 值類型是 .NET 中很重要的性能工具,被頻繁使用,但是此前 struct 并沒有在 JIT 中得到應得的優(yōu)化。在 .NET 5 和 .NET 6 中,將針對 struct 進行性能優(yōu)化,一部分是確保 struct 能夠被加載到 CPU 寄存器中進行訪問。 Preview 1 中包含如下改進:
結語 以上就是個人認為值得關注的 .NET 6 Preview 1 帶來的新特性了,后續(xù)還會有十個左右的預覽版本,會包含更多的新增和改進內容,敬請期待吧。
|
|
|