HTML5技术

是什么优化让 .NET Core 性能飙升? - 葡萄城控件技术团队(8)

字号+ 作者:H5之家 来源:H5之家 2017-07-17 17:00 我要评论( )

using System; using System.Diagnostics; using System.Linq; public class Test{ Main(){ , ; while ( true ){ var sw = Stopwatch.StartNew(); for ( int i = 0 ; i 100_000_000; i++ ){s.IndexOf( );}Console.W

using System; using System.Diagnostics; using System.Linq; public class Test { Main() { , ; while (true) { var sw = Stopwatch.StartNew(); for (int i = 0; i < 100_000_000; i++) { s.IndexOf(); } Console.WriteLine(sw.Elapsed); } } }

在.NET 4.7上会得到如下结果:

::0001.3210207

.NET Core 2.0会得到如下结果:

::0000.6099822

String的改进,也让我们看到对于其它方面进行更多改进的可能性,这是非常有趣的。

 

文件系统

到目前为止,本文一直专注于内存中操纵数据的各种改进。但是.NET Core的许多更改都是关于I / O的。

下面从文件开始介绍。这是一个从文件中异步读取所有数据并将其写入另一个文件的示例:

using System; using System.Diagnostics; using System.IO; using System.Threading.Tasks; class Test { static void Main() => MainAsync().GetAwaiter().GetResult(); static async Task MainAsync() { string inputPath = Path.GetTempFileName(), outputPath = Path.GetTempFileName(); byte[] data = new byte[50_000_000]; new Random().NextBytes(data); File.WriteAllBytes(inputPath, data); var sw = new Stopwatch(); int gen0 = GC.CollectionCount(0), gen1 = GC.CollectionCount(1), gen2 = GC.CollectionCount(2); sw.Start(); for (int i = 0; i < 100; i++) { using (var input = new FileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, 0x1000, useAsync: true)) using (var output = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 0x1000, useAsync: true)) { await input.CopyToAsync(output); } } Console.WriteLine($); } }

 

Elapsed=00:00:09.4070345 Gen0=14 Gen1=7 Gen2=1

.NET Core 2.0会得到如下结果:

Elapsed=00:00:06.4286604 Gen0=4 Gen1=1 Gen2=1

 

网络

网络是值得关注的部分,这部分也将取得很大的改进。目前正在付出很大的努力来优化和调整低等级的网络堆栈,以便高效地构建更高级别的组件。

这种改变带来的一个很大的影响是PR dotnet / corefx#15141SocketAsyncEventArgsSocket上大量异步操作的核心,它支持同步完成模型,因此异步操作实际完成了同步操作,这样避免了异步操作的分配消耗。但是,.NET 4.7中的同步操作运算是失败的, PR修复了上述的实现问题,允许在socket上进行所有异步操作的同步完成。这样的提升在以下代码中变现的非常明显:

using System; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; class Test { static void Main() { using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); listener.Listen(1); Task connectTask = Task.Run(() => client.Connect(listener.LocalEndPoint)); using (Socket server = listener.Accept()) { connectTask.Wait(); using (var clientAre = new AutoResetEvent(false)) using (var clientSaea = new SocketAsyncEventArgs()) using (var serverAre = new AutoResetEvent(false)) using (var serverSaea = new SocketAsyncEventArgs()) { byte[] sendBuffer = new byte[1000]; clientSaea.SetBuffer(sendBuffer, 0, sendBuffer.Length); clientSaea.Completed += delegate { clientAre.Set(); }; byte[] receiveBuffer = new byte[1000]; serverSaea.SetBuffer(receiveBuffer, 0, receiveBuffer.Length); serverSaea.Completed += delegate { serverAre.Set(); }; var sw = new Stopwatch(); int gen0 = GC.CollectionCount(0), gen1 = GC.CollectionCount(1), gen2 = GC.CollectionCount(2); sw.Start(); for (int i = 0; i < 1_000_000; i++) { if (client.SendAsync(clientSaea)) clientAre.WaitOne(); if (clientSaea.SocketError != SocketError.Success) throw new SocketException((int)clientSaea.SocketError); if (server.ReceiveAsync(serverSaea)) serverAre.WaitOne(); if (serverSaea.SocketError != SocketError.Success) throw new SocketException((int)clientSaea.SocketError); } Console.WriteLine($); } } } } }

该程序创建两个连接的socket,然后向socket写入1000次,并且在案例中使用异步方法接收,但绝大多数操作将同步完成。在.NET 4.7中会得到如下结果:

Elapsed=00:00:20.5272910 Gen0=42 Gen1=2 Gen2=0

在.NET Core 2.0中,大多数操作能够同步完成,得到如下结果:

Elapsed=00:00:05.6197060 Gen0=0 Gen1=0 Gen2=0

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 十年过去了,各位 .net 兄弟还好吗 - 精密~顽石

    十年过去了,各位 .net 兄弟还好吗 - 精密~顽石

    2017-07-17 16:03

  • ASP.NET Core之跨平台的实时性能监控 - GuZhenYin

    ASP.NET Core之跨平台的实时性能监控 - GuZhenYin

    2017-07-15 13:00

  • 在Visual Studio 2017中使用Asp.Net Core构建Angular4应用程序 - SmallProg

    在Visual Studio 2017中使用Asp.Net Core构建Angular4应用程序 - Sma

    2017-07-08 16:01

  • 【原创】 Docker 中 运行 ASP.NET Core 站点 - Meng.NET

    【原创】 Docker 中 运行 ASP.NET Core 站点 - Meng.NET

    2017-07-06 11:00

网友点评