【译】ASP.NET Core 6 中的性能改进 (3)

另一个类似大小的更改是 dotnet/runtime#49123,它增加了对 SslStream 中零字节读取的支持,因此我们的 10,000 个空闲连接从 SslStream 分配中从 ~46 MB 变为 ~2.3 MB。 dotnet/runtime#49117 在 StreamPipeReader 上添加了对零字节读取的支持,然后 Kestrel 在 dotnet/aspnetcore#30863 中使用它开始在 SslStream 中使用零字节读取。

所有这些变化的结果是大量减少了空闲连接的内存使用量。

以下数字并非来自 BenchmarkDotNet 应用程序,因为它正在测量空闲连接,并且使用客户端和服务器应用程序进行设置更容易。

控制台和 WebApplication 代码粘贴在以下要点中:https://gist.github.com/BrennanConroy/02e8459d63305b4acaa0a021686f54c7

下面是不同框架上服务器上 10,000 个空闲安全 WebSocket 连接 (WSS) 占用的内存量。

Framework Memory
net48   665.4 MB  
net5.0   603.1 MB  
net6.0   160.8 MB  

从 net5.0 到 net6.0,内存减少了近 4 倍!

Entity Framework Core

EF Core 在 6.0 中进行了一些重大改进,执行查询的速度提高了 31%,而 通过运行时更新、优化基准测试和 EF 改进提高了 70%。

这些改进来自改进对象池、智能地检查遥测是否启用,以及当您知道您的应用程序安全地使用 DbContext 时添加一个选项以选择退出线程安全检查。

请参阅宣布 Entity Framework Core 6.0 Preview 4:Performance Edition 博客文章,其中详细介绍了许多改进。

Blazor 本地 byte[] 互通

Blazor 现在在执行 JavaScript 互操作时有效地支持字节数组。以前,向 JavaScript 发送和从 JavaScript 发送的字节数组是 Base64 编码的,因此它们可以序列化为 JSON,这增加了传输大小和 CPU 负载。 Base64 编码现已在 .NET 6 中进行了优化,允许用户透明地使用 .NET 中的 byte[] 和 JavaScript 中的 Uint8Array。有关将此功能用于 和 的文档。

让我们看一个快速基准测试,以了解 .NET 5 和 .NET 6 中的 byte[] 互操作之间的区别。以下 Razor 代码创建一个 22 kB byte[],并将其发送到 JavaScript 的 receiveAndReturnBytes 函数,该函数立即返回字节[]。此数据往返重复 10,000 次,并将时间数据打印到屏幕上。此代码与 .NET 5 和 .NET 6 相同。

<button @onclick="@RoundtripData">Roundtrip Data</button> <hr /> @Message @code { public string Message { get; set; } = "Press button to benchmark"; private async Task RoundtripData() { var bytes = new byte[1024*22]; List<double> timeForInterop = new List<double>(); var testTime = DateTime.Now; for (var i = 0; i < 10_000; i++) { var interopTime = DateTime.Now; var result = await JSRuntime.InvokeAsync<byte[]>("receiveAndReturnBytes", bytes); timeForInterop.Add(DateTime.Now.Subtract(interopTime).TotalMilliseconds); } Message = $"Round-tripped: {bytes.Length / 1024d} kB 10,000 times and it took on average {timeForInterop.Average():F3}ms, and in total {DateTime.Now.Subtract(testTime).TotalMilliseconds:F1}ms"; } }

接下来我们看一下receiveAndReturnBytes JavaScript 函数。在 .NET 5 中。我们必须首先将 Base64 编码的字节数组解码为 Uint8Array,以便它可以在应用程序代码中使用。然后我们必须在将数据返回到服务器之前将其重新编码为 Base64。

function receiveAndReturnBytes(bytesReceivedBase64Encoded) { const bytesReceived = base64ToArrayBuffer(bytesReceivedBase64Encoded); // Use Uint8Array data in application const bytesToSendBase64Encoded = base64EncodeByteArray(bytesReceived); if (bytesReceivedBase64Encoded != bytesToSendBase64Encoded) { throw new Error("Expected input/output to match.") } return bytesToSendBase64Encoded; } // https://stackoverflow.com/a/21797381 function base64ToArrayBuffer(base64) { const binaryString = atob(base64); const length = binaryString.length; const result = new Uint8Array(length); for (let i = 0; i < length; i++) { result[i] = binaryString.charCodeAt(i); } return result; } function base64EncodeByteArray(data) { const charBytes = new Array(data.length); for (var i = 0; i < data.length; i++) { charBytes[i] = String.fromCharCode(data[i]); } const dataBase64Encoded = btoa(charBytes.join('')); return dataBase64Encoded; }

编码/解码增加了客户端和服务器的大量开销,同时还需要大量的样板代码。那么这将如何在 .NET 6 中完成呢?好吧,它有点简单:

function receiveAndReturnBytes(bytesReceived) { // bytesReceived comes as a Uint8Array ready for use // and can be used by the application or immediately returned. return bytesReceived; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgzfdg.html