Reduce ProbabilisticWithAsciiCharSearchValues overhead on non-ASCII texts (#89224)
authorMiha Zupan <mihazupan.zupan1@gmail.com>
Thu, 20 Jul 2023 03:01:07 +0000 (05:01 +0200)
committerGitHub <noreply@github.com>
Thu, 20 Jul 2023 03:01:07 +0000 (23:01 -0400)
src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticWithAsciiCharSearchValues.cs

index 065f2cd..8a8f09a 100644 (file)
@@ -40,7 +40,9 @@ namespace System.Buffers
         {
             int offset = 0;
 
-            if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && span.Length >= Vector128<short>.Count)
+            // We check whether the first character is ASCII before calling into IndexOfAnyAsciiSearcher
+            // in order to minimize the overhead this fast-path has on non-ASCII texts.
+            if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && span.Length >= Vector128<short>.Count && char.IsAscii(span[0]))
             {
                 // We are using IndexOfAnyAsciiSearcher to search for the first ASCII character in the set, or any non-ASCII character.
                 // We do this by inverting the bitmap and using the opposite search function (Negate instead of DontNegate).
@@ -100,7 +102,9 @@ namespace System.Buffers
         {
             int offset = 0;
 
-            if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && span.Length >= Vector128<short>.Count)
+            // We check whether the first character is ASCII before calling into IndexOfAnyAsciiSearcher
+            // in order to minimize the overhead this fast-path has on non-ASCII texts.
+            if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && span.Length >= Vector128<short>.Count && char.IsAscii(span[0]))
             {
                 // Do a regular IndexOfAnyExcept for the ASCII characters. The search will stop if we encounter a non-ASCII char.
                 offset = IndexOfAnyAsciiSearcher.IndexOfAnyVectorized<IndexOfAnyAsciiSearcher.Negate, TOptimizations>(
@@ -134,7 +138,9 @@ namespace System.Buffers
 
         internal override int LastIndexOfAny(ReadOnlySpan<char> span)
         {
-            if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && span.Length >= Vector128<short>.Count)
+            // We check whether the last character is ASCII before calling into IndexOfAnyAsciiSearcher
+            // in order to minimize the overhead this fast-path has on non-ASCII texts.
+            if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && span.Length >= Vector128<short>.Count && char.IsAscii(span[^1]))
             {
                 // We are using IndexOfAnyAsciiSearcher to search for the last ASCII character in the set, or any non-ASCII character.
                 // We do this by inverting the bitmap and using the opposite search function (Negate instead of DontNegate).
@@ -186,7 +192,9 @@ namespace System.Buffers
 
         internal override int LastIndexOfAnyExcept(ReadOnlySpan<char> span)
         {
-            if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && span.Length >= Vector128<short>.Count)
+            // We check whether the last character is ASCII before calling into IndexOfAnyAsciiSearcher
+            // in order to minimize the overhead this fast-path has on non-ASCII texts.
+            if (IndexOfAnyAsciiSearcher.IsVectorizationSupported && span.Length >= Vector128<short>.Count && char.IsAscii(span[^1]))
             {
                 // Do a regular LastIndexOfAnyExcept for the ASCII characters. The search will stop if we encounter a non-ASCII char.
                 int offset = IndexOfAnyAsciiSearcher.LastIndexOfAnyVectorized<IndexOfAnyAsciiSearcher.Negate, TOptimizations>(