很高興.NET 6 預覽版5終于跟大家見面了,我們現在正處于.NET 6 的后半部分,開始整合一些重要的功能, 例如.NET SDK 作業負載,它是我們.NET 統一愿景的基礎,可以支持更多型別的應用程式, 與其他功能一樣,它也是為了更好地服務于端到端的用戶體驗,
您可以下載適用于Linux、macOS 和Windows 的.NET 6 預覽版5,
- 安裝程式和二進制檔案
- 容器鏡像
- Linux 軟體包
- 發行說明
- API差異
- 已知的問題
- GitHub 問題跟蹤器
請參閱ASP.NET Core、EF Core以及.NET MAUI,了解有關Web、資料訪問和跨平臺UI 方案新增功能的更多詳細資訊,
Visual Studio 2022 預覽版1 也在今天發布,.NET 6 預覽版5包含其中,.NET 6 還在Visual Studio 16.11和Visual Studio for Mac 8.9進行了測驗, 如果您想在Visual Studio中試用.NET 6,我們建議您使用這些版本,
您也可以查看新的對話帖,深入了解工程師們對.NET新功能的想法,
.NET SDK:可選的作業負載改進
SDK 作業負載是一項新的.NET SDK 功能,它使我們能夠在不增加SDK 大小的情況下添加對新應用程式型別(如移動和WebAssembly)的支持,
作業負載添加了包括list 和update 指令,這些新功能提供了與我們期望的最終體驗一致的使用感受,您將能夠使用一些簡單的指令快速構建您的環境,并一直將其保持最新狀態,
- dotnet workload list 會告訴您安裝了哪些作業負載,
- dotnet workload update 會將所有已安裝的作業負載更新到最新的可用版本,
update 指令會查詢nuget.org 以獲取更新的作業負載清單、更新本地清單、下載已安裝作業負載的新版本,然后洗掉作業負載的所有舊版本,這類似于apt update 和apt upgrade -y(用于基于Debian 的Linux 發行版),
dotnet workload 命令集在給定SDK 的背景關系中運行,假設您同時安裝了.NET 6 和.NET 7,如果您同時使用兩者,則作業負載命令將提供不同的結果,因為作業負載會有所不同(至少是相同作業負載的不同版本),
如您所見,作業負載功能本質上是.NET SDK 的包管理器,作業負載最初是在.NET 6 預覽版4版本中引入的,
.NET SDK:NuGet 包驗證
包驗證工具將使NuGet 庫開發人員能夠驗證他們的包是否一致且格式良好的,
這包括:
- 驗證不同版本之間沒有重大更改,
- 驗證包對于所有特定運行時具有相同的公共 API 集,
- 識別任何與目標框架或運行時適用性之間的差距,
此工具可通過Microsoft.DotNet.PackageValidation獲得,
有關此工具的帖子很快就會發布,
.NET SDK:更多Roslyn 分析器
在.NET 5 中,我們隨.NET SDK 提供了大約250 個分析器, 其中許多已經存在,但我們將其作為NuGet 包另行發布, 我們正在為.NET 6 添加更多分析器,
默認情況下,大多數新分析器應用在Info級別,您可以通過如下AnalysisMode的配置在Warning級別啟用這些分析器:
\<AnalysisMode\>AllEnabledByDefault\</AnalysisMode\>
我們發布了我們想要的.NET 6 分析器集(加上一些額外的東西),然后將其中的大部分都公開了,
預覽版5 中包含了Newell Clark和Meik Tranel的以下實作,請注意,社區用戶在之前的預覽版中貢獻了其他實作,
| Contributor | Issue | Title |
|---|---|---|
| Newell Clark | dotnet/runtime #33777 | Use span-based string.Concat |
| Newell Clark | dotnet/runtime #33784 | Prefer string.AsSpan() over string.Substring() when parsing |
| Newell Clark | dotnet/runtime #33789 | Override Stream.ReadAsync/WriteAsync |
| Newell Clark | dotnet/runtime #35343 | Replace Dictionary<,>.Keys.Contains with ContainsKey |
| Newell Clark | dotnet/runtime #45552 | Use String.Equals instead of String.Compare |
| Meik Tranel | dotnet/runtime #47180 | Use String.Contains(char) instead of String.Contains(String) |
.NET SDK:為平臺兼容性分析器啟用自定義防護
CA1416 平臺兼容性分析器已經使用OperatingSystem/RuntimeInformation 中的方法識別平臺保護,例如OperatingSystem.IsWindows 和OperatingSystem.IsWindowsVersionAtLeast, 但是,分析器不識別任何其他保護可能性,例如快取在欄位或屬性中的平臺檢查結果,或者在輔助方法中定義了復雜的平臺檢查邏輯,
為了使自定義保護成為可能,我們添加了新屬性SupportedOSPlatformGuard 和UnsupportedOSPlatformGuard,可以使用相應的平臺名稱和/或版本注釋自定義保護物件, 平臺兼容性分析器的流分析邏輯識別并尊重這些注釋的內容,
用法
[UnsupportedOSPlatformGuard("browser")] // The platform guard attribute
#if TARGET_BROWSER
internal bool IsSupported => false;
#else
internal bool IsSupported => true;
#endif
[UnsupportedOSPlatform("browser")]
void ApiNotSupportedOnBrowser() { }
void M1()
{
ApiNotSupportedOnBrowser(); // Warns: This call site is reachable on all platforms.'ApiNotSupportedOnBrowser()' is unsupported on: 'browser'
if (IsSupported)
{
ApiNotSupportedOnBrowser(); // Not warn
}
}
[SupportedOSPlatform("Windows")]
[SupportedOSPlatform("Linux")]
void ApiOnlyWorkOnWindowsLinux() { }
[SupportedOSPlatformGuard("Linux")]
[SupportedOSPlatformGuard("Windows")]
private readonly bool _isWindowOrLinux = OperatingSystem.IsLinux() || OperatingSystem.IsWindows();
void M2()
{
ApiOnlyWorkOnWindowsLinux(); // This call site is reachable on all platforms.'ApiOnlyWorkOnWindowsLinux()' is only supported on: 'Linux', 'Windows'.
if (_isWindowOrLinux)
{
ApiOnlyWorkOnWindowsLinux(); // Not warn
}
}
}
Windows Forms: 默認字體
您現在可以使用Application.SetDefaultFont 為應用程式設定默認字體, 您使用的模式類似于設定high dpi或視覺樣式,
class Program
{
[STAThread]
static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
+ Application.SetDefaultFont(new Font(new FontFamily("Microsoft Sans Serif"), 8f));
Application.Run(new Form1());
}
}
下面是設定默認字體后的兩個例子(使用不同的字體),
Microsoft Sans Serif, 8pt:

Chiller, 12pt:

.NET Core 3.0 中更新了默認字體,這一變化為一些用戶將.NET Framework 應用程式遷移到.NET Core 帶來了很大的阻礙, 默認字體設定使為應用程式選擇所需字體變得簡單,消除了遷移的障礙,
庫:放棄對舊框架的支持
從包中洗掉框架是一個破壞源代碼的改動,但是,讓它一直支持我們發布的所有框架也增加了包的復雜性和大小,過去,我們通過_harvesting_來解決這個問題,也就是:
- 我們只為"當前"支持的框架做構建
- 在構建期間,我們下載包的早期版本,并切除我們不再構建的早期框架的二進制檔案
雖然這意味著您可以隨時更新而不必擔心我們會洗掉框架,但這也意味著如果您使用切割過的二進制檔案,您將永遠不會獲得任何錯誤修復或新功能,換句話說,切割過的無法提供服務的資產,現在已經被隱藏了,因為從您的角度來看,您可以繼續將包更新到更高版本,即使您正在使用我們不再更新的舊二進制檔案,
從.NET 6 Preview 5 開始,我們計劃不再執行任何形式的harvesting,以確保我們為交付的所有內容都得到更好的服務,這意味著我們將放棄對任何早于以下版本的支持:
- .NET Framework 4.6.1
- .NET Core 3.1
- .NET Standard 2.0
如果您當前正在參考來自早期框架的受影響的包,您將無法再將參考的包更新到更高版本,您可以將您的專案重新指向到更高版本的框架或選擇不更新參考的包(這通常不是一個大的回退,因為無論如何您已經在使用凍結的二進制檔案),
更多詳細資訊,包括受影響軟體包的完整串列,請參閱dotnet/announcement:洗掉舊框架版本,
庫:Microsoft.Extensions
我們一直在改進此版本的Microsoft.Extensions API, 在預覽版5 中,我們專注于托管和依賴注入, 在預覽版4 中,我們添加了一個用于日志記錄的編譯時源生成器,
感謝Martin Bj?rkstr?m](https://github.com/bjorkstromm) 的dotnet/runtime #51840 (AsyncServiceScope),
托管 – ConfigureHostOptions API
我們在IHostBuilder 上添加了一個新的ConfigureHostOptions API 以簡化應用程式配置(例如配置超時關閉):
using HostBuilder host = new()
.ConfigureHostOptions(o =>
{
o.ShutdownTimeout = TimeSpan.FromMinutes(10);
})
.Build();
host.Run();
在預覽版5 之前,配置更加復雜一些:
using HostBuilder host = new()
.ConfigureServices(services =>
{
services.Configure<HostOptions>(o =>
{
o.ShutdownTimeout = TimeSpan.FromMinutes(10);
});
})
.Build();
host.Run();
依賴注入 – CreateAsyncScope API
您可能已經注意到,當服務提供者注冊了IAsyncDisposable 服務時,其銷毀會拋出InvalidOperationException,
新的CreateAsyncScope API 提供了一個很直接的解決方案,如以下示例所示:
await using (var scope = provider.CreateAsyncScope())
{
var foo = scope.ServiceProvider.GetRequiredService<Foo>();
}
以下示例演示了現有的問題案例,并演示了此前建議的解決方法,
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
await using var provider = new ServiceCollection()
.AddScoped<Foo>()
.BuildServiceProvider();
// This using can throw InvalidOperationException
using (var scope = provider.CreateScope())
{
var foo = scope.ServiceProvider.GetRequiredService<Foo>();
}
class Foo : IAsyncDisposable
{
public ValueTask DisposeAsync() => default;
}
您可以通過將回傳的scope強制轉換為IAsyncDisposable 來繞過例外,
var scope = provider.CreateScope();
var foo = scope.ServiceProvider.GetRequiredService<Foo>();
await ((IAsyncDisposable)scope).DisposeAsync();
CreateAsyncScope 解決了這個問題,使您可以安全地使用using 陳述句,
庫:JsonSerializer 原始碼生成器
幾乎所有.NET 序列化工具的支柱都是反射機制,反射對于某些場景來說是一個很棒的功能,但不適用于高性能云原生應用程式(因其通常需要處理大量序列化反序列化作業和JSON 檔案),過多的反射使用會引起一些程式啟動、記憶體使用和程式集修整上的問題,
運行時反射的替代方法是編譯時源代碼生成,原始碼生成器生成C# 源檔案,這些檔案可以作為庫或應用程式構建的一部分進行編譯,在編譯時生成源代碼可以為.NET 應用程式提供許多好處,包括性能的提升,
在.NET 6 中,我們在System.Text.Json 中引入了一個新的原始碼生成器,JSON 原始碼生成器與JsonSerializer 協同作業,并且可以配置成多種多樣的作業方式,是否使用新的原始碼生成器由您決定,它可以提供以下好處:
- 減少啟動時間
- 提高序列化吞吐量
- 減少私有記憶體使用
- 移除運行時System.Reflection 和System.Reflection.Emit 的使用
- 允許兼容trim的JSON 序列化
例如,原始碼生成器可以生成對properties更簡單有效的賦值/取值的代碼,而不是在運行時通過Reflection.Emit生成get和set方法(這會用到私有記憶體并且影響啟動速度),使得性能得到了更大的提高,
您可以使用System.Text.Json NuGet 包的最新預覽版來試用原始碼生成器,我們正在提議在SDK 中包含原始碼生成器,
生成優化的序列化邏輯
默認情況下,JSON 原始碼生成器為給定的可序列化型別應用序列化邏輯,這比直接使用現有JsonSerializer 來生成使用 Utf8JsonWriter 的原始碼提供了更高的性能, 簡而言之,源生成器提供了一種在編譯時應用的不同實作方法,以優化程式的運行時體驗,
宏觀來講,JsonSerializer 是一個強大的工具,它有許多可以改進.NET 型別和JSON 格式之間序列化和反序列化的功能(甚至還有更多即將實作的新功能!), 它速度很快,但是當序列化例程只需要一個功能子集時,它也會產生一些性能開銷, 展望未來,我們將同時更新JsonSerializer 和新的原始碼生成器,
給定一個簡單類:
namespace Test
{
internal class JsonMessage
{
public string Message { get; set; }
}
}
源生成器可以配置為為JsonMessage 類的實體生成序列化邏輯, 請注意,類名JsonContext 是任意的, 您可以為生成的原始碼使用任何您想要的類名,
using System.Text.Json.Serialization;
namespace Test
{
[JsonSerializable(typeof(JsonMessage)]
internal partial class JsonContext : JsonSerializerContext
{
}
}
我們通過JsonSerializerOptionsAttribute 定義了一組JsonSerializer 功能,這些功能由提供最佳序列化吞吐量的原始碼生成模式提供, 這些功能可以提前指定給原始碼生成器,以避免在運行時進行額外檢查, 如果該屬性未宣告,運行時會使用默認的JsonSerializationOptions,
作為構建的一部分,原始碼生成器用以下內容擴充JsonContext 部分類:
internal partial class JsonContext : JsonSerializerContext
{
public static JsonContext Default { get; }
public JsonTypeInfo<JsonMessage> JsonMessage { get; }
public JsonContext(JsonSerializerOptions options) { }
public override JsonTypeInfo GetTypeInfo(Type type) => ...;
}
使用此模式的序列化程式呼叫可能類似于以下示例,此示例提供了可能的最佳性能,
using MemoryStream ms = new();
using Utf8JsonWriter writer = new(ms);
JsonContext.Default.JsonMessage.Serialize(writer, new JsonMessage { "Hello, world!" });
writer.Flush();
// Writer contains:
// {"Message":"Hello, world!"}
或者,您可以繼續使用JsonSerializer,并且使用JsonContext.Default.JsonMessage 將生成代碼的實體傳遞給它,
JsonSerializer.Serialize(jsonMessage, JsonContext.Default.JsonMessage);
這是一個類似的用法,但多載方法不同,
JsonSerializer.Serialize(jsonMessage, typeof(JsonMessage), JsonContext.Default);
這兩個多載之間的區別在于,第一個多載使用型別化元資料實作 — JsonTypeInfo<T> — 第二個使用更通用的無型別化實作,該實作執行型別測驗以確定背景關系實體中是否存在型別化實作,因此,它有點慢(由于型別測驗),如果給定型別沒有原始碼生成的實作,則序列化程式會拋出NotSupportedException,但是它不會回退到基于反射的實作(我們的設計明確了這一點),
基于Utf8JsonWriter的最快、最優化的原始碼生成模式目前僅可用于序列化,我們會根據您的反饋決定是否在未來提供基于Utf8JsonReader的反序列化實作,
但是,原始碼生成器還提供型別元資料初始化邏輯,這也有助于反序列化,要使用預先生成的型別元資料反序列化JsonMessage 的實體,您可以執行以下操作:
JsonSerializer.Deserialize(json, JsonContext.Default.JsonMessage);
類似于上面的序列化,你也可以這樣寫:
JsonSerializer.Deserialize(json, typeof(JsonMessage), JsonContext.Default);
補充筆記
- 可以通過派生的部分JsonSerializerContext 實體上的[JsonSerializable] 包含多種型別以用于源生成,不止支持一個,
- 源生成器還支持嵌套物件和集合成員,而不僅僅是原始型別,
庫:WebSocket 壓縮
壓縮對于通過網路傳輸的任何資料都很重要,WebSockets 現在啟用壓縮,我們使用了WebSockets 的permessage-deflate 擴展實作,RFC 7692,它允許使用DEFLATE 演算法壓縮WebSockets 訊息有效負載,
此功能是用戶對GitHub 上Networking 的最高要求之一,您可以通過API 審查1和API 審查2跟隨我們提供該API 的程序,
歸功于Ivan Zlatanov,謝謝Ivan!
我們意識到將壓縮與加密結合使用可能會導致攻擊,例如CRIME和BREACH,這意味著不能在單個壓縮背景關系中將秘密與用戶生成的資料一起發送,否則可以提取該秘密,為了讓用戶注意這些影響并幫助他們權衡風險,我們將API 重命名為DangerousDeflateOptions,我們還添加了對特定訊息關閉壓縮的功能,因此如果用戶想要發送秘密,他們可以在不壓縮的情況下安全地發送,
Ivan還進行了一項后續作業,當禁用壓縮時,WebSocket 的記憶體占用減少了約27%,
從客戶端啟用壓縮很容易,請參見下面的示例,但是,請記住服務器可以協商設定,例如請求較小的視窗,或完全拒絕壓縮,
var cws = new ClientWebSocket();
cws.Options.DangerousDeflateOptions = new WebSocketDeflateOptions()
{
ClientMaxWindowBits = 10,
ServerMaxWindowBits = 10
};
最近還添加了對ASP.NET Core 的WebSocket 壓縮支持, 它將包含在即將發布的預覽中,
庫:Socks 代理支持
SOCKS是一種代理服務器實作,可以處理任何TCP 或UDP 流量,使其成為一個非常通用的系統, 這是一個長期存在的社區請求,已添加到.NET 6 中,
此更改增加了對Socks4、Socks4a 和Socks5 的支持, 例如,它允許通過SSH 測驗外部連接或連接到Tor 網路,
WebProxy 類現在接受socks 方案,如下例所示,
var handler = new HttpClientHandler
{
Proxy = new WebProxy("socks5://127.0.0.1", 9050)
};
var httpClient = new HttpClient(handler);
歸功于Huo Yaoyuan,謝謝Huo!
庫:支持OpenTelemetry 指標
作為我們關注可觀察性的一部分,我們一直在為最近的幾個.NET 版本添加對OpenTelemetry 的支持,在.NET 6 中,我們添加了對OpenTelemetry Metrics API的支持,通過添加對OpenTelemetry的支持,您的應用程式可以與其他OpenTelemetry 系統無縫互操作,
System.Diagnostics.Metrics是OpenTelemetry Metrics API 規范的.NET 實作,Metrics API 是專門為處理原始測量而設計的,通常旨在高效且同時地生成這些測量的連續摘要,
API 包括可用于創建儀器物件(例如計數器)的Meter 類,API 公開了四個儀器類:Counter、Histogram、ObservableCounter 和ObservableGauge,以支持不同的指標場景,此外,API 公開MeterListener 類以允許偵聽儀器記錄的測量以進行聚合和分組,
OpenTelemetry .NET 實作將擴展為使用這些新API,這些API 增加了對Metrics 可觀察性場景的支持,
庫測量記錄示例
Meter meter = new Meter("io.opentelemetry.contrib.mongodb", "v1.0");
Counter<int> counter = meter.CreateCounter<int>("Requests");
counter.Add(1);
counter.Add(1, KeyValuePair.Create<string, object>("request", "read"));
聽力示例
MeterListener listener = new MeterListener();
listener.InstrumentPublished = (instrument, meterListener) =>
{
if (instrument.Name == "Requests" && instrument.Meter.Name == "io.opentelemetry.contrib.mongodb")
{
meterListener.EnableMeasurementEvents(instrument, null);
}
};
listener.SetMeasurementEventCallback<int>((instrument, measurement, tags, state) =>
{
Console.WriteLine($"Instrument: {instrument.Name} has recorded the measurement {measurement}");
});
listener.Start();
庫:BigInteger 性能
從十進制和十六進制字串決議BigIntegers 已得到改進, 我們看到了高達89% 的改進,如下圖所示,

歸功于Joseph Da Silva, 謝謝Joseph!
庫:Vector<T> 現在支持nint 和nuint
Vector<T> 現在支持在C# 9 中添加的nint 和nuint 基元型別,例如,此更改應該可以更輕松地使用具有指標或平臺相關長度的SIMD 指令,
庫:支持OpenSSL 3
.NET 加密API 支持使用OpenSSL 3作為Linux 上的首選本機加密提供程式, 如果可用,.NET 6 將使用OpenSSL 3, 否則,它將使用OpenSSL 1.x,
庫:添加支持ChaCha20/Poly1305 加密演算法
ChaCha20Poly1305 類已添加到System.Security.Cryptography, 要使用ChaCha20/Poly1305演算法,必須得到底層作業系統的支持, 靜態IsSupported 屬性可用于確定在給定背景關系中是否支持該演算法,
- Linux:需要OpenSSL 1.1 或更高版本,
- Windows:構建20142 或更高版本(目前需要開發"內部人員"頻道)
感謝Kevin Jones對Linux 的支持, 謝謝Kevin!
互操作性:Objective-C 互操作性支持
該團隊一直在添加Objective-C 支持,目標是為.NET 提供單一的Objective-C 互操作實作, 到目前為止,Objective-C互作業系統是圍繞Mono 嵌入API 構建的,但我們認為這不是跨運行時共享的正確方法, 因此,我們創建了一個新的.NET API,它將支持單一的Objective-C 互操作體驗,最終將在兩個運行時上運行,
這個用于Objective-C 互操作的新API 為NSAutoreleasePool的兩個運行時帶來了即時支持,從而支持Cocoa 的參考計數記憶體管理系統, 您現在可以配置是否希望每個托管執行緒都具有隱式NSAutoreleasePool, 這使得在每個執行緒的基礎上釋放Cocoa 物件成為可能,
診斷(EventPipe/DiagnosticsServer)——MonoVM
從.NET 6 開始,MonoVM 中添加了許多診斷功能,這啟用了托管EventSource/EventListener、EventPipe 和DiagnosticsServer 等功能, 它支持使用診斷工具,如dotnet-trace、dotnet-counters、dotnet-stacks,用于在移動設備(iOS/Android) 和桌面上運行的應用程式,
這些新功能開啟了在PrefView/SpeedScope/Chromium、dotnet-trace等工具中分析MonoVM 生成的nettrace 檔案的能力,或使用TraceEvent等庫撰寫自定義決議器,
我們將繼續包含更多功能,主要側重于SDK 集成并將更多本地運行時事件(Microsoft-Windows-DotNETRuntime) 適配到MonoVM 中,從而在nettrace 檔案中啟用更多事件,
現已具備以下功能:
- 在MonoVM 和CoreCLR 之間共享本機EventPipe/DiagnosticsServer 庫,
- 將TCP/IP 支持添加到DiagnosticsServer 并利用該配置構建MonoVM iOS/Android 運行時包,需要以支持移動平臺,
- BCL EventSources 在MonoVM 上運行,將事件發送到EventPipe,
- System.Diagnostics.Tracing.RuntimeEventSource 發出的BCL 運行時計數器連接到MonoVM,可從dotnet-counters 等工具消耗,
- 自定義事件源在MonoVM 上運行,將自定義事件發送到EventPipe,可通過dotnet-trace 等工具使用,
- 自定義事件計數器在MonoVM 上運行,將自定義計數器事件發送到EventPipe,可通過dotnet-counters 等工具使用,
- 示例分析器在MonoVM 上實作,將事件發送到EventPipe,開啟了使用dotnet-trace 在MonoVM 上進行CPU 分析的能力,
- dotnet-dsrouter 診斷工具的實作,允許使用現有的診斷工具,如dotnet-trace、dotnet-counters、dotnet-stack 以及在移動目標上運行的MonoVM,無需更改現有工具,dotnet-dsrouter 運行本地IPC 服務器,將所有流量從診斷工具路由到在模擬器/設備上的MonoVM 中運行的DiagnosticsServer,
- 使用基于組件的架構在MonoVM 中實作EventPipe/DiagnosticsServer,
- 基于檔案會話的診斷環境的實作/擴展,
iOS CPU 采樣(SpeedScope)
下圖演示了在SpeedScope 中查看的iOS 啟動CPU 采樣會話的一部分,

Android CPU 采樣(PerfView)
下圖演示了在PerfView(無限睡眠中的主執行緒)中查看的Android CPU 采樣,

運行時:CodeGen
RyuJIT 中進行了以下更改,
社區貢獻
- 洗掉未使用的dummyBB 變數 https://github.com/dotnet/runtime/pull/52155
- 洗掉未使用的函式,以大端格式讀取整數https://github.com/dotnet/runtime/pull/52154
- 將TYP_FLOAT 傳遞給gtNewDconNode 而不是創建新范圍 https://github.com/dotnet/runtime/pull/51928
感謝@SingleAccretion的這些貢獻,
動態PGO
- 修改行內規模計算https://github.com/dotnet/runtime/pull/51593
- 使用排除塊檢查更新optReachable https://github.com/dotnet/runtime/pull/51842
- 概括圍繞空流優化的分支https://github.com/dotnet/runtime/pull/51409
- 為新的GetLikelyClass PGO 記錄型別添加MCS jitflags 支持 https://github.com/dotnet/runtime/pull/51578
- 在尾呼叫后概括檢查有效IR 以支持crossgen2 確定性 https://github.com/dotnet/runtime/pull/51903
- 更通用的價值類去虛擬化https://github.com/dotnet/runtime/pull/52210
- 鏈式保護去虛擬化https://github.com/dotnet/runtime/pull/51890

JIT 回圈優化
- 改進的回圈反轉在BenchE 中顯示出良好的性能提升 https://github.com/dotnet/runtime/pull/52347<img src="https://img.uj5u.com/2021/08/31/259480311551237.png" width="600″ height="120″>
- 縮放克隆回圈塊權重https://github.com/dotnet/runtime/pull/51901
- 在回圈克隆期間不要重新計算preds 串列以保留邊緣上的現有組態檔資料 https://github.com/dotnet/runtime/pull/51757
- 改進DOT 流圖轉儲 https://github.com/dotnet/runtime/pull/52329
- 改進回圈展開檔案https://github.com/dotnet/runtime/pull/52099
LSRA
在"分配暫存器"表中包含暫存器選擇啟發式https://github.com/dotnet/runtime/pull/52513新舊表的差異:

保持結構在注冊
- 為暫存器中的結構準備JIT 后端 https://github.com/dotnet/runtime/pull/52039
- struct enreg 的活性修復https://github.com/dotnet/runtime/pull/51851
- 改進結構初始化以將ASG struct(LCL_VAR, 0) 保持為STORE_LCL_VAR struct(0) https://github.com/dotnet/runtime/pull/52292
優化除錯經驗
- 為nint/nuint 識別和處理Vector64/128/256 https://github.com/dotnet/runtime/pull/52016
- 添加clrjit.natvis 檔案以獲得更好的除錯體驗 https://github.com/dotnet/runtime/pull/52668 jitstd::list 的示例可視化工具以及RefPosition 和內部registerAssignment 的分解以顯示所有暫存器:

SIMD
涉及SIMD 或HWIintrinsics 的某些方法的行內現在應該具有改進的代碼生成和性能, 我們看到了高達95% 的改進,

結束
就功能的廣度和數量而言,.NET 6 預覽版5 可能是迄今為止最大的預覽版, 您可以使用源生成器和分析器查看Roslyn 功能對低級庫功能的影響程度, 未來真的到來了, 我們現在擁有一個非常強大的編譯器工具鏈,使我們能夠生成高度優化和正確的代碼,并為您自己的專案提供完全相同的體驗,
現在是開始測驗.NET 6 的好時機,現在我們根據您的反饋采取行動還為時過早, 很難想象,雖然我們要到2021 年11 月才會發布,但反饋視窗很快就會縮小到僅針對高嚴重性問題, 該團隊提前進行了大約一年半的預覽,并將很快轉向主要關注質量問題, 如果可以,請嘗試.NET 6,
感謝您成為.NET 開發人員,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/295824.html
