Optimize `System.Reflection.Metadata.ByteSequenceComparer`. (#70047)
authorTheodore Tsirpanis <teo@tsirpanis.gr>
Thu, 7 Jul 2022 22:01:36 +0000 (01:01 +0300)
committerGitHub <noreply@github.com>
Thu, 7 Jul 2022 22:01:36 +0000 (18:01 -0400)
src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj
src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj
src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ByteSequenceComparer.cs
src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/Hash.cs
src/libraries/System.Reflection.Metadata/tests/Utilities/HashTests.cs

index 5818f02..0017ce6 100644 (file)
@@ -102,7 +102,7 @@ The System.Collections.Immutable library is built-in as part of the shared frame
   </ItemGroup>
 
   <ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
-    <PackageReference Include="System.Memory"  Version="$(SystemMemoryVersion)" />
+    <PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
   </ItemGroup>
 
   <ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">
index cdd0d0a..90eeff0 100644 (file)
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@@ -259,10 +259,15 @@ System.Reflection.PortableExecutable.ManagedPEBuilder</PackageDescription>
     <ProjectReference Include="$(LibrariesProjectRoot)System.Collections.Immutable\src\System.Collections.Immutable.csproj" />
   </ItemGroup>
 
+  <ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
+    <PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
+  </ItemGroup>
+
   <ItemGroup Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)'">
     <Reference Include="System.Collections" />
     <Reference Include="System.IO.Compression" />
     <Reference Include="System.IO.MemoryMappedFiles" />
+    <Reference Include="System.Memory" />
     <Reference Include="System.Runtime" />
     <Reference Include="System.Runtime.InteropServices" />
     <Reference Include="System.Text.Encoding.Extensions" />
index 89e4ce9..2ddd180 100644 (file)
@@ -18,71 +18,17 @@ namespace System.Reflection.Internal
 
         internal static bool Equals(ImmutableArray<byte> x, ImmutableArray<byte> y)
         {
-            if (x == y)
-            {
-                return true;
-            }
-
-            if (x.IsDefault || y.IsDefault || x.Length != y.Length)
-            {
-                return false;
-            }
-
-            for (var i = 0; i < x.Length; i++)
-            {
-                if (x[i] != y[i])
-                {
-                    return false;
-                }
-            }
-
-            return true;
+            return x.AsSpan().SequenceEqual(y.AsSpan());
         }
 
         internal static bool Equals(byte[] left, int leftStart, byte[] right, int rightStart, int length)
         {
-            if (left == null || right == null)
-            {
-                return ReferenceEquals(left, right);
-            }
-
-            if (ReferenceEquals(left, right) && leftStart == rightStart)
-            {
-                return true;
-            }
-
-            for (var i = 0; i < length; i++)
-            {
-                if (left[leftStart + i] != right[rightStart + i])
-                {
-                    return false;
-                }
-            }
-
-            return true;
+            return left.AsSpan(leftStart, length).SequenceEqual(right.AsSpan(rightStart, length));
         }
 
         internal static bool Equals(byte[]? left, byte[]? right)
         {
-            if (ReferenceEquals(left, right))
-            {
-                return true;
-            }
-
-            if (left == null || right == null || left.Length != right.Length)
-            {
-                return false;
-            }
-
-            for (var i = 0; i < left.Length; i++)
-            {
-                if (left[i] != right[i])
-                {
-                    return false;
-                }
-            }
-
-            return true;
+            return left.AsSpan().SequenceEqual(right.AsSpan());
         }
 
         // Both hash computations below use the FNV-1a algorithm (http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function).
@@ -96,7 +42,7 @@ namespace System.Reflection.Internal
         internal static int GetHashCode(ImmutableArray<byte> x)
         {
             Debug.Assert(!x.IsDefault);
-            return Hash.GetFNVHashCode(x);
+            return Hash.GetFNVHashCode(x.AsSpan());
         }
 
         bool IEqualityComparer<byte[]>.Equals(byte[]? x, byte[]? y)
index 5479d9d..d083ff1 100644 (file)
@@ -40,25 +40,7 @@ namespace System.Reflection.Internal
         /// </summary>
         /// <param name="data">The sequence of bytes</param>
         /// <returns>The FNV-1a hash of <paramref name="data"/></returns>
-        internal static int GetFNVHashCode(byte[] data)
-        {
-            int hashCode = Hash.FnvOffsetBias;
-
-            for (int i = 0; i < data.Length; i++)
-            {
-                hashCode = unchecked((hashCode ^ data[i]) * Hash.FnvPrime);
-            }
-
-            return hashCode;
-        }
-
-        /// <summary>
-        /// Compute the FNV-1a hash of a sequence of bytes
-        /// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
-        /// </summary>
-        /// <param name="data">The sequence of bytes</param>
-        /// <returns>The FNV-1a hash of <paramref name="data"/></returns>
-        internal static int GetFNVHashCode(ImmutableArray<byte> data)
+        internal static int GetFNVHashCode(ReadOnlySpan<byte> data)
         {
             int hashCode = Hash.FnvOffsetBias;
 
index ade18ea..b1cc1c0 100644 (file)
@@ -18,7 +18,7 @@ namespace System.Reflection.Metadata.Tests
         [Fact]
         public void GetFNVHashCodeImmutableByteTest()
         {
-            Assert.Equal(-1088511923, Hash.GetFNVHashCode(ImmutableArray.Create((byte)0xFF, (byte)0xD1)));
+            Assert.Equal(-1088511923, Hash.GetFNVHashCode(ImmutableArray.Create((byte)0xFF, (byte)0xD1).AsSpan()));
         }
 
         [Fact]