ASP.NET Core 6 的性能改进( 二 )


需要注意的是 , 天下没有免费的午餐 。 在新的 QueryStringEnumerable API 的情况下 , 如果您计划多次枚举查询字符串值 , 它实际上可能比使用 QueryHelpers.ParseQuery 并存储已解析查询字符串值的字典更昂贵 。
@paulomorgado 的 dotnet/aspnetcore#29448 使用 string.Create 方法 , 如果您知道字符串的最终大小 , 则该方法允许在创建字符串后对其进行初始化 。 这是用来移除 UriHelper.BuildAbsolute 中的一些临时字符串分配 。
dotnet run -c Release -f netcoreapp3.1 --runtimes netcoreapp3.1 net6.0 --filter *UriHelperBenchmark*

#if NETCOREAPP[Benchmark]public void BuildAbsolute{_ = UriHelper.BuildAbsolute("https", new HostString("localhost"));}#endifPR dotnet/aspnetcore#31267 将 ContentDispositionHeaderValue 中的一些解析逻辑转换为使用基于 Span<T> 的 API , 以避免在常见情况下出现临时字符串和临时 byte[] 。
dotnet run -c Release -f net48 --runtimes net48 netcoreapp3.1 net5.0 net6.0 --filter *ContentDispositionBenchmark*[Benchmark]public void ParseContentDispositionHeader{var contentDisposition = new ContentDispositionHeaderValue("inline");contentDisposition.FileName = "File?Name.bat";}
  • github 上提供了 repo https://github.com/BrennanConroy/BlogPost60Bench
  • BenchmarkDotNet https://github.com/dotnet/benchmarkdotnet
  • github
    https://github.com/BrennanConroy/BlogPost60Bench
  • .NET 6 RC1的构建
    https://github.com/dotnet/installer/blob/main/README.md#installers-and-binaries
  • 最新发布的.NET 5和.NET Core 3.1下载
    https://dotnet.microsoft.com/en-us/download
  • Span<T>
    https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/january/csharp-all-about-span-exploring-a-new-net-mainstay
  • dotnet/aspnetcore#28855
    https://github.com/dotnet/aspnetcore/pull/28855
  • dotnet/aspnetcore#34001
    https://github.com/dotnet/aspnetcore/pull/34001
  • 新的 QueryStringEnumerable API
    https://en.wikipedia.org/wiki/There_ain%27t_no_such_thing_as_a_free_lunch
  • paulomorgado
    https://github.com/paulomorgado
  • dotnet/aspnetcore#29448
    https://github.com/dotnet/aspnetcore/pull/29448
  • string.Create
    https://docs.microsoft.com/en-us/dotnet/api/system.string.create?view=net-6.0
  • dotnet/aspnetcore#31267
    https://github.com/dotnet/aspnetcore/pull/31267
空闲连接
ASP.NET Core 的主要组件之一是托管服务器 , 它带来了许多不同的问题需要去优化 。 我们将重点关注6.0中空闲连接的改进 , 在其中我们做了许多更改 , 以减少连接等待数据时所使用的内存量 。
我们进行了三种不同类型的更改 , 一种是减少连接使用的对象的大小 , 这包括System.IO.Pipelines、SocketConnections 和 SocketSenders 。 第二种类型的更改是将常用访问的对象池化 , 这样我们就可以重用旧实例并节省分配 。 第三种类型的改变是利用所谓的“零字节读取” 。 在这里 , 我们尝试用一个零字节缓冲区从连接中读取数据 , 如果有可用的数据 ,, 读取将返回没有数据 , 但我们知道现在有可用的数据 , 可以提供一个缓冲区来立即读取该数据 。 这避免了为将来可能完成的读取预先分配一个缓冲区 , 所以在知道数据可用之前 , 我们可以避免大量的分配 。
dotnet/runtime#49270 将 System.IO.Pipelines 的大小从 ~560 字节减少到 ~368 字节 , 减少了34% , 每个连接至少有2个管道 , 所以这是一个巨大的胜利 。
dotnet/aspnetcore#31308重构了 Kestrel 的 Socket 层 , 以避免一些异步状态机 , 并减少剩余状态机的大小 , 从而为每个连接节省33%的分配 。

特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。