From bb641e13a24c1d76ed5b80bf41ab693daa4d4c5c Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Apr 2023 11:13:46 -0500 Subject: [PATCH] Use optimized hash creation methods on .NET 5+ --- .../Workspace/Solution/Checksum_Factory.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Checksum_Factory.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Checksum_Factory.cs index 5dcf4f0a2367e..bfc1b283da99c 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Checksum_Factory.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Checksum_Factory.cs @@ -34,6 +34,19 @@ internal partial class Checksum public static Checksum Create(IEnumerable values) { +#if NET5_0_OR_GREATER + using var pooledHash = s_incrementalHashPool.GetPooledObject(); + + foreach (var value in values) + { + pooledHash.Object.AppendData(MemoryMarshal.AsBytes(value.AsSpan())); + pooledHash.Object.AppendData(MemoryMarshal.AsBytes("\0".AsSpan())); + } + + Span hash = stackalloc byte[SHA256HashSizeBytes]; + pooledHash.Object.GetHashAndReset(hash); + return From(hash); +#else using var pooledHash = s_incrementalHashPool.GetPooledObject(); using var pooledBuffer = SharedPools.ByteArray.GetPooledObject(); var hash = pooledHash.Object; @@ -45,10 +58,16 @@ public static Checksum Create(IEnumerable values) } return From(hash.GetHashAndReset()); +#endif } public static Checksum Create(string value) { +#if NET5_0_OR_GREATER + Span hash = stackalloc byte[SHA256HashSizeBytes]; + SHA256.HashData(MemoryMarshal.AsBytes(value.AsSpan()), hash); + return From(hash); +#else using var pooledHash = s_incrementalHashPool.GetPooledObject(); using var pooledBuffer = SharedPools.ByteArray.GetPooledObject(); var hash = pooledHash.Object; @@ -56,10 +75,34 @@ public static Checksum Create(string value) AppendData(hash, pooledBuffer.Object, value); return From(hash.GetHashAndReset()); +#endif } public static Checksum Create(Stream stream) { +#if NET7_0_OR_GREATER + Span hash = stackalloc byte[SHA256HashSizeBytes]; + SHA256.HashData(stream, hash); + return From(hash); +#elif NET5_0_OR_GREATER + using var pooledHash = s_incrementalHashPool.GetPooledObject(); + Span buffer = stackalloc byte[SharedPools.ByteBufferSize]; + + int bytesRead; + do + { + bytesRead = stream.Read(buffer); + if (bytesRead > 0) + { + pooledHash.Object.AppendData(buffer[..bytesRead]); + } + } + while (bytesRead > 0); + + Span hash = stackalloc byte[SHA256HashSizeBytes]; + pooledHash.Object.GetHashAndReset(hash); + return From(hash); +#else using var pooledHash = s_incrementalHashPool.GetPooledObject(); using var pooledBuffer = SharedPools.ByteArray.GetPooledObject(); @@ -91,6 +134,7 @@ public static Checksum Create(Stream stream) // hash algorithm used here should remain functionally correct even // after the truncation return From(bytes); +#endif } public static Checksum Create(IObjectWritable @object)