一个关键的例子是压缩,例如使用DeflateStream,性能方面也有一些重大的性能改进。例如,在.NET 4.7中,zlib(本地压缩库)用于压缩数据,但是相对未优化的托管实现了用于解压缩的数据; PR dotnet / corefx#2906添加了.NET Core支持,以便使用zlib进行解压缩。来自bjjones的 PR dotnet / corefx#5674使用英特尔生产的zlib这个更优化的版本。这些结合产生了非常棒的效果。下面的例子,创建一个大量的数据:
using System; using System.IO; using System.IO.Compression; using System.Diagnostics; public class Test { Main() { [] raw = new byte[100 * 1024 * 1024]; for (int i = 0; i < raw.Length; i++) raw[i] = (byte)i; var sw = Stopwatch.StartNew(); compressed = new MemoryStream(); using (DeflateStream ds = new DeflateStream(compressed, CompressionMode.Compress, true)) { ds.Write(raw, 0, raw.Length); } compressed.Position = 0; decompressed = new MemoryStream(); using (DeflateStream ds = new DeflateStream(compressed, CompressionMode.Decompress)) { ds.CopyTo(decompressed); } decompressed.Position = 0; Console.WriteLine(sw.Elapsed); } }
在.NET 4.7中,这一个压缩/解压缩操作,会得到如下结果:
00:00:00.7977190
而使用.NET Core 2.0,会得到如下结果:
00:00:00.1926701
加密
.NET应用程序中另一个常见的计算源是使用加密操作,在这方面.NET Core也有改进。例如,在.NET 4.7中,SHA256.Create返回在管理代码中实现的SHA256类型,而管理代码可以运行得非常快,但是对于运算量非常大的计算,这仍然难以与原始吞吐量和编译器优化竞争。相反,对于.NET Core 2.0,SHA256.Create返回基于底层操作系统的实现,例如在Windows上使用CNG或在Unix上使用OpenSSL。从下面这个简单的例子可以看出,它散列着一个100MB的字节数组:
using System; using System.Diagnostics; using System.Security.Cryptography; public class Test { Main() { byte[] raw = new byte[100 * 1024 * 1024]; for (int i = 0; i < raw.Length; i++) raw[i] = (byte)i; using (var sha = SHA256.Create()) { var sw = Stopwatch.StartNew(); sha.ComputeHash(raw); Console.WriteLine(sw.Elapsed); } } }
在.NET 4.7中,会得到:
00:00:00.7576808
而使用.NET Core 2.0,会得到:
00:00:00.4032290
零代码更改的一个很好提升。
数学运算
数学运算也是一个很大的计算量,特别是处理大量数据时。通过像dotnet / corefx#2182这样的PR ,axelheer对BigInteger的各种操作做了一些实质的改进。请考虑以下示例:
using System; using System.Diagnostics; using System.Numerics; public class Test { Main() { var rand = new Random(42); BigInteger a = Create(rand, 8192); BigInteger b = Create(rand, 8192); BigInteger c = Create(rand, 8192); var sw = Stopwatch.StartNew(); BigInteger.ModPow(a, b, c); Console.WriteLine(sw.Elapsed); } private static BigInteger Create(Random rand, int bits) { var value = new byte[(bits + 7) / 8 + 1]; rand.NextBytes(value); value[value.Length - 1] = 0; return new BigInteger(value); } }
在.NET 4.7中,会得到以下输出结果:
00:00:05.6024158
.NET Core 2.0上的相同代码会得到输出结果如下:
00:00:01.2707089
这是开发人员只关注.NET的某个特定领域的一个很好的例子,开发人员使得这种改进更好的满足了自己的需求,同时也满足了可能会用到这方面功能的其他开发人员的需求。
一些核心的整型类型的数学运算也得到了改进。例如: