-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Add Vector512/Vector256 SIMD acceleration to UTF-8 utility functions #120628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -102,6 +102,136 @@ internal static bool EqualsStringIgnoreCaseNonAsciiUtf8(ref byte strA, int lengt | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static bool EqualsIgnoreCaseUtf8_Vector512(ref byte charA, int lengthA, ref byte charB, int lengthB) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Debug.Assert(lengthA >= Vector512<byte>.Count); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Debug.Assert(lengthB >= Vector512<byte>.Count); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Debug.Assert(Vector512.IsHardwareAccelerated); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nuint lengthU = Math.Min((uint)lengthA, (uint)lengthB); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nuint lengthToExamine = lengthU - (nuint)Vector512<byte>.Count; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nuint i = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Vector512<byte> vec1; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Vector512<byte> vec2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vec1 = Vector512.LoadUnsafe(ref charA, i); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vec2 = Vector512.LoadUnsafe(ref charB, i); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!Utf8Utility.AllBytesInVector512AreAscii(vec1 | vec2)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| goto NON_ASCII; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!Utf8Utility.Vector512OrdinalIgnoreCaseAscii(vec1, vec2)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| i += (nuint)Vector512<byte>.Count; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while (i <= lengthToExamine); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (i == lengthU) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // success if we reached the end of both sequences | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return lengthA == lengthB; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Use Vector256 path for trailing elements if possible | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (Vector256.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector256<byte>.Count) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return EqualsIgnoreCaseUtf8_Vector256(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Use Vector128 path for trailing elements if possible | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (Vector128.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector128<byte>.Count) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return EqualsIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Use scalar path for trailing elements | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return EqualsIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+147
to
+157
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return EqualsIgnoreCaseUtf8_Vector256(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| } | |
| // Use Vector128 path for trailing elements if possible | |
| if (Vector128.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector128<byte>.Count) | |
| { | |
| return EqualsIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return EqualsIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| return EqualsIgnoreCaseUtf8_Vector256(ref Unsafe.Add(ref charA, i), (int)(lengthA - i), ref Unsafe.Add(ref charB, i), (int)(lengthB - i)); | |
| } | |
| // Use Vector128 path for trailing elements if possible | |
| if (Vector128.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector128<byte>.Count) | |
| { | |
| return EqualsIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref charA, i), (int)(lengthA - i), ref Unsafe.Add(ref charB, i), (int)(lengthB - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return EqualsIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref charA, i), (int)(lengthA - i), ref Unsafe.Add(ref charB, i), (int)(lengthB - i)); |
Copilot
AI
Oct 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining length calculation is incorrect. It should pass the actual remaining lengths of each string, not the minimum remaining length for both strings. This could cause buffer overruns or incorrect comparisons when the strings have different lengths.
| return EqualsIgnoreCaseUtf8_Vector256(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| } | |
| // Use Vector128 path for trailing elements if possible | |
| if (Vector128.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector128<byte>.Count) | |
| { | |
| return EqualsIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return EqualsIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| return EqualsIgnoreCaseUtf8_Vector256(ref Unsafe.Add(ref charA, i), (int)(lengthA - (int)i), ref Unsafe.Add(ref charB, i), (int)(lengthB - (int)i)); | |
| } | |
| // Use Vector128 path for trailing elements if possible | |
| if (Vector128.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector128<byte>.Count) | |
| { | |
| return EqualsIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref charA, i), (int)(lengthA - (int)i), ref Unsafe.Add(ref charB, i), (int)(lengthB - (int)i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return EqualsIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref charA, i), (int)(lengthA - (int)i), ref Unsafe.Add(ref charB, i), (int)(lengthB - (int)i)); |
Copilot
AI
Oct 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining length calculation is incorrect. It should pass the actual remaining lengths of each string, not the minimum remaining length for both strings. This could cause buffer overruns or incorrect comparisons when the strings have different lengths.
| return EqualsIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return EqualsIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| return EqualsIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref charA, i), (int)(lengthA - i), ref Unsafe.Add(ref charB, i), (int)(lengthB - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return EqualsIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref charA, i), (int)(lengthA - i), ref Unsafe.Add(ref charB, i), (int)(lengthB - i)); |
Copilot
AI
Oct 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining length calculation is incorrect. It should pass the actual remaining lengths of each string, not the minimum remaining length for both strings. This could cause buffer overruns or incorrect comparisons when the strings have different lengths.
| return EqualsIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return EqualsIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref charA, i), (int)(lengthU - i), ref Unsafe.Add(ref charB, i), (int)(lengthU - i)); | |
| return EqualsIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref charA, i), (int)(lengthA - i), ref Unsafe.Add(ref charB, i), (int)(lengthB - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return EqualsIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref charA, i), (int)(lengthA - i), ref Unsafe.Add(ref charB, i), (int)(lengthB - i)); |
Copilot
AI
Oct 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining length calculation is incorrect. It should pass the actual remaining lengths of each string, not the minimum remaining length for both strings. This could cause buffer overruns or incorrect comparisons when the strings have different lengths.
| return StartsWithIgnoreCaseUtf8_Vector256(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| } | |
| // Use Vector128 path for trailing elements if possible | |
| if (Vector128.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector128<byte>.Count) | |
| { | |
| return StartsWithIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| return StartsWithIgnoreCaseUtf8_Vector256(ref Unsafe.Add(ref source, i), (int)(sourceLength - i), ref Unsafe.Add(ref prefix, i), (int)(prefixLength - i)); | |
| } | |
| // Use Vector128 path for trailing elements if possible | |
| if (Vector128.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector128<byte>.Count) | |
| { | |
| return StartsWithIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref source, i), (int)(sourceLength - i), ref Unsafe.Add(ref prefix, i), (int)(prefixLength - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), (int)(sourceLength - i), ref Unsafe.Add(ref prefix, i), (int)(prefixLength - i)); |
Copilot
AI
Oct 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining length calculation is incorrect. It should pass the actual remaining lengths of each string, not the minimum remaining length for both strings. This could cause buffer overruns or incorrect comparisons when the strings have different lengths.
| return StartsWithIgnoreCaseUtf8_Vector256(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| } | |
| // Use Vector128 path for trailing elements if possible | |
| if (Vector128.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector128<byte>.Count) | |
| { | |
| return StartsWithIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| return StartsWithIgnoreCaseUtf8_Vector256(ref Unsafe.Add(ref source, i), sourceLength - (int)i, ref Unsafe.Add(ref prefix, i), prefixLength - (int)i); | |
| } | |
| // Use Vector128 path for trailing elements if possible | |
| if (Vector128.IsHardwareAccelerated && (lengthU - i) >= (nuint)Vector128<byte>.Count) | |
| { | |
| return StartsWithIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref source, i), sourceLength - (int)i, ref Unsafe.Add(ref prefix, i), prefixLength - (int)i); | |
| } | |
| // Use scalar path for trailing elements | |
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), sourceLength - (int)i, ref Unsafe.Add(ref prefix, i), prefixLength - (int)i); |
Copilot
AI
Oct 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining length calculation is incorrect. It should pass the actual remaining lengths of each string, not the minimum remaining length for both strings. This could cause buffer overruns or incorrect comparisons when the strings have different lengths.
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), (int)(sourceLength - i), ref Unsafe.Add(ref prefix, i), (int)(prefixLength - i)); |
Copilot
AI
Oct 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining length calculation is incorrect. It should pass the actual remaining lengths of each string, not the minimum remaining length for both strings. This could cause buffer overruns or incorrect comparisons when the strings have different lengths.
| return StartsWithIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| return StartsWithIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref source, i), (int)(sourceLength - i), ref Unsafe.Add(ref prefix, i), (int)(prefixLength - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), (int)(sourceLength - i), ref Unsafe.Add(ref prefix, i), (int)(prefixLength - i)); |
Copilot
AI
Oct 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining length calculation is incorrect. It should pass the actual remaining lengths of each string, not the minimum remaining length for both strings. This could cause buffer overruns or incorrect comparisons when the strings have different lengths.
| return StartsWithIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), (int)(lengthU - i), ref Unsafe.Add(ref prefix, i), (int)(lengthU - i)); | |
| return StartsWithIgnoreCaseUtf8_Vector128(ref Unsafe.Add(ref source, i), (int)(sourceLength - i), ref Unsafe.Add(ref prefix, i), (int)(prefixLength - i)); | |
| } | |
| // Use scalar path for trailing elements | |
| return StartsWithIgnoreCaseUtf8_Scalar(ref Unsafe.Add(ref source, i), (int)(sourceLength - i), ref Unsafe.Add(ref prefix, i), (int)(prefixLength - i)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining length calculation is incorrect. It should pass the actual remaining lengths of each string, not the minimum remaining length for both strings. This could cause buffer overruns or incorrect comparisons when the strings have different lengths.