Skip to content

Commit f9287b5

Browse files
committed
Optimise Guid.DecodeByte
1 parent 7416d91 commit f9287b5

File tree

1 file changed

+50
-49
lines changed
  • src/libraries/System.Private.CoreLib/src/System

1 file changed

+50
-49
lines changed

src/libraries/System.Private.CoreLib/src/System/Guid.cs

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -516,25 +516,25 @@ private static bool TryParseExactD<TChar>(ReadOnlySpan<TChar> guidString, ref Gu
516516
}
517517

518518
Span<byte> bytes = MemoryMarshal.AsBytes(new Span<GuidResult>(ref result));
519-
int invalidIfNegative = 0;
520-
bytes[0] = DecodeByte(guidString[6], guidString[7], ref invalidIfNegative);
521-
bytes[1] = DecodeByte(guidString[4], guidString[5], ref invalidIfNegative);
522-
bytes[2] = DecodeByte(guidString[2], guidString[3], ref invalidIfNegative);
523-
bytes[3] = DecodeByte(guidString[0], guidString[1], ref invalidIfNegative);
524-
bytes[4] = DecodeByte(guidString[11], guidString[12], ref invalidIfNegative);
525-
bytes[5] = DecodeByte(guidString[9], guidString[10], ref invalidIfNegative);
526-
bytes[6] = DecodeByte(guidString[16], guidString[17], ref invalidIfNegative);
527-
bytes[7] = DecodeByte(guidString[14], guidString[15], ref invalidIfNegative);
528-
bytes[8] = DecodeByte(guidString[19], guidString[20], ref invalidIfNegative);
529-
bytes[9] = DecodeByte(guidString[21], guidString[22], ref invalidIfNegative);
530-
bytes[10] = DecodeByte(guidString[24], guidString[25], ref invalidIfNegative);
531-
bytes[11] = DecodeByte(guidString[26], guidString[27], ref invalidIfNegative);
532-
bytes[12] = DecodeByte(guidString[28], guidString[29], ref invalidIfNegative);
533-
bytes[13] = DecodeByte(guidString[30], guidString[31], ref invalidIfNegative);
534-
bytes[14] = DecodeByte(guidString[32], guidString[33], ref invalidIfNegative);
535-
bytes[15] = DecodeByte(guidString[34], guidString[35], ref invalidIfNegative);
536-
537-
if (invalidIfNegative >= 0)
519+
uint invalidIfGreaterThan7F = 0;
520+
bytes[0] = DecodeByte(guidString[6], guidString[7], ref invalidIfGreaterThan7F);
521+
bytes[1] = DecodeByte(guidString[4], guidString[5], ref invalidIfGreaterThan7F);
522+
bytes[2] = DecodeByte(guidString[2], guidString[3], ref invalidIfGreaterThan7F);
523+
bytes[3] = DecodeByte(guidString[0], guidString[1], ref invalidIfGreaterThan7F);
524+
bytes[4] = DecodeByte(guidString[11], guidString[12], ref invalidIfGreaterThan7F);
525+
bytes[5] = DecodeByte(guidString[9], guidString[10], ref invalidIfGreaterThan7F);
526+
bytes[6] = DecodeByte(guidString[16], guidString[17], ref invalidIfGreaterThan7F);
527+
bytes[7] = DecodeByte(guidString[14], guidString[15], ref invalidIfGreaterThan7F);
528+
bytes[8] = DecodeByte(guidString[19], guidString[20], ref invalidIfGreaterThan7F);
529+
bytes[9] = DecodeByte(guidString[21], guidString[22], ref invalidIfGreaterThan7F);
530+
bytes[10] = DecodeByte(guidString[24], guidString[25], ref invalidIfGreaterThan7F);
531+
bytes[11] = DecodeByte(guidString[26], guidString[27], ref invalidIfGreaterThan7F);
532+
bytes[12] = DecodeByte(guidString[28], guidString[29], ref invalidIfGreaterThan7F);
533+
bytes[13] = DecodeByte(guidString[30], guidString[31], ref invalidIfGreaterThan7F);
534+
bytes[14] = DecodeByte(guidString[32], guidString[33], ref invalidIfGreaterThan7F);
535+
bytes[15] = DecodeByte(guidString[34], guidString[35], ref invalidIfGreaterThan7F);
536+
537+
if (invalidIfGreaterThan7F <= 0x7F)
538538
{
539539
if (!BitConverter.IsLittleEndian)
540540
{
@@ -602,25 +602,25 @@ private static bool TryParseExactN<TChar>(ReadOnlySpan<TChar> guidString, ref Gu
602602
}
603603

604604
Span<byte> bytes = MemoryMarshal.AsBytes(new Span<GuidResult>(ref result));
605-
int invalidIfNegative = 0;
606-
bytes[0] = DecodeByte(guidString[6], guidString[7], ref invalidIfNegative);
607-
bytes[1] = DecodeByte(guidString[4], guidString[5], ref invalidIfNegative);
608-
bytes[2] = DecodeByte(guidString[2], guidString[3], ref invalidIfNegative);
609-
bytes[3] = DecodeByte(guidString[0], guidString[1], ref invalidIfNegative);
610-
bytes[4] = DecodeByte(guidString[10], guidString[11], ref invalidIfNegative);
611-
bytes[5] = DecodeByte(guidString[8], guidString[9], ref invalidIfNegative);
612-
bytes[6] = DecodeByte(guidString[14], guidString[15], ref invalidIfNegative);
613-
bytes[7] = DecodeByte(guidString[12], guidString[13], ref invalidIfNegative);
614-
bytes[8] = DecodeByte(guidString[16], guidString[17], ref invalidIfNegative);
615-
bytes[9] = DecodeByte(guidString[18], guidString[19], ref invalidIfNegative);
616-
bytes[10] = DecodeByte(guidString[20], guidString[21], ref invalidIfNegative);
617-
bytes[11] = DecodeByte(guidString[22], guidString[23], ref invalidIfNegative);
618-
bytes[12] = DecodeByte(guidString[24], guidString[25], ref invalidIfNegative);
619-
bytes[13] = DecodeByte(guidString[26], guidString[27], ref invalidIfNegative);
620-
bytes[14] = DecodeByte(guidString[28], guidString[29], ref invalidIfNegative);
621-
bytes[15] = DecodeByte(guidString[30], guidString[31], ref invalidIfNegative);
622-
623-
if (invalidIfNegative >= 0)
605+
uint invalidIfGreaterThan7F = 0;
606+
bytes[0] = DecodeByte(guidString[6], guidString[7], ref invalidIfGreaterThan7F);
607+
bytes[1] = DecodeByte(guidString[4], guidString[5], ref invalidIfGreaterThan7F);
608+
bytes[2] = DecodeByte(guidString[2], guidString[3], ref invalidIfGreaterThan7F);
609+
bytes[3] = DecodeByte(guidString[0], guidString[1], ref invalidIfGreaterThan7F);
610+
bytes[4] = DecodeByte(guidString[10], guidString[11], ref invalidIfGreaterThan7F);
611+
bytes[5] = DecodeByte(guidString[8], guidString[9], ref invalidIfGreaterThan7F);
612+
bytes[6] = DecodeByte(guidString[14], guidString[15], ref invalidIfGreaterThan7F);
613+
bytes[7] = DecodeByte(guidString[12], guidString[13], ref invalidIfGreaterThan7F);
614+
bytes[8] = DecodeByte(guidString[16], guidString[17], ref invalidIfGreaterThan7F);
615+
bytes[9] = DecodeByte(guidString[18], guidString[19], ref invalidIfGreaterThan7F);
616+
bytes[10] = DecodeByte(guidString[20], guidString[21], ref invalidIfGreaterThan7F);
617+
bytes[11] = DecodeByte(guidString[22], guidString[23], ref invalidIfGreaterThan7F);
618+
bytes[12] = DecodeByte(guidString[24], guidString[25], ref invalidIfGreaterThan7F);
619+
bytes[13] = DecodeByte(guidString[26], guidString[27], ref invalidIfGreaterThan7F);
620+
bytes[14] = DecodeByte(guidString[28], guidString[29], ref invalidIfGreaterThan7F);
621+
bytes[15] = DecodeByte(guidString[30], guidString[31], ref invalidIfGreaterThan7F);
622+
623+
if (invalidIfGreaterThan7F <= 0x7F)
624624
{
625625
if (!BitConverter.IsLittleEndian)
626626
{
@@ -813,20 +813,21 @@ private static bool TryParseExactX<TChar>(ReadOnlySpan<TChar> guidString, ref Gu
813813
}
814814

815815
[MethodImpl(MethodImplOptions.AggressiveInlining)]
816-
private static byte DecodeByte<TChar>(TChar ch1, TChar ch2, ref int invalidIfNegative) where TChar : unmanaged, IUtfChar<TChar>
816+
private static byte DecodeByte<TChar>(TChar ch1, TChar ch2, ref uint invalidIfGreaterThan7F)
817+
where TChar : unmanaged, IUtfChar<TChar>
817818
{
818819
ReadOnlySpan<byte> lookup = HexConverter.CharToHexLookup;
819820
Debug.Assert(lookup.Length == 256);
820-
int upper = (sbyte)lookup[byte.CreateTruncating(ch1)];
821-
int lower = (sbyte)lookup[byte.CreateTruncating(ch2)];
822-
int result = (upper << 4) | lower;
823-
824-
uint c1 = TChar.CastToUInt32(ch1);
825-
uint c2 = TChar.CastToUInt32(ch2);
826-
// Result will be negative if ch1 or/and ch2 are greater than 0xFF
827-
result = (c1 | c2) >> 8 == 0 ? result : -1;
828-
invalidIfNegative |= result;
829-
return (byte)result;
821+
822+
int c1 = typeof(TChar) == typeof(byte) ? byte.CreateTruncating(ch1) : (int)Math.Min(TChar.CastToUInt32(ch1), 0x7F);
823+
uint upper = lookup[c1];
824+
invalidIfGreaterThan7F |= upper;
825+
826+
int c2 = typeof(TChar) == typeof(byte) ? byte.CreateTruncating(ch2) : (int)Math.Min(TChar.CastToUInt32(ch2), 0x7F);
827+
uint lower = lookup[c2];
828+
invalidIfGreaterThan7F |= lower;
829+
830+
return (byte)((upper << 4) | lower);
830831
}
831832

832833
private static bool TryParseHex<TChar>(ReadOnlySpan<TChar> guidString, out ushort result, ref bool overflow) where TChar : unmanaged, IUtfChar<TChar>

0 commit comments

Comments
 (0)