From 3a3ad11b05153d5cf8902b737f8fb69c50b15d9d Mon Sep 17 00:00:00 2001 From: brian-reichle <18721383+brian-reichle@users.noreply.github.com> Date: Tue, 17 Feb 2026 18:22:09 +1000 Subject: [PATCH] Performance tuning in ConvertShims.DecoderCore. --- .../FrameworkExtensions/ConvertShims.cs | 63 +++++++++++-------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/TypeNameInterpretation/FrameworkExtensions/ConvertShims.cs b/src/TypeNameInterpretation/FrameworkExtensions/ConvertShims.cs index eb2af6a..d1ece6b 100644 --- a/src/TypeNameInterpretation/FrameworkExtensions/ConvertShims.cs +++ b/src/TypeNameInterpretation/FrameworkExtensions/ConvertShims.cs @@ -2,6 +2,8 @@ #if !NET9_0_OR_GREATER using System.Buffers; using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using TypeNameInterpretation; namespace System; @@ -50,24 +52,48 @@ public static OperationStatus FromHexString(ReadOnlySpan source, Span source, Span target) + => DecoderCore(ref MemoryMarshal.GetReference(source), ref MemoryMarshal.GetReference(target), source.Length); + + static bool DecoderCore(ref char source, ref byte target, int sourceLength) { - var read = 0; - var write = 0; var halfByte = false; var highNibble = 0; - while (read < source.Length) + ref var sourcePtr = ref source; + ref var targetPtr = ref target; + + while (sourceLength > 0) { - var nibble = CharValue(source[read++]); + var c = sourcePtr; + byte nibble; - if (nibble < 0) + unchecked { - return false; + var tmp = (uint)(c - '0'); + + if (tmp <= 9) + { + nibble = (byte)tmp; + } + else + { + tmp = (uint)((c | '\x20') - 'a'); + + if (tmp <= 5) + { + nibble = (byte)(tmp + 10); + } + else + { + return false; + } + } } if (halfByte) { - target[write++] = (byte)(nibble | highNibble); + targetPtr = (byte)(nibble | highNibble); + targetPtr = ref Unsafe.Add(ref targetPtr, 1); halfByte = false; } else @@ -75,29 +101,12 @@ static bool DecoderCore(ReadOnlySpan source, Span target) highNibble = nibble << 4; halfByte = true; } + + sourceLength--; + sourcePtr = ref Unsafe.Add(ref sourcePtr, 1); } return true; } - - static int CharValue(char c) - { - if (c >= '0' && c <= '9') - { - return c - '0'; - } - else if (c >= 'a' && c <= 'f') - { - return c - 'a' + 10; - } - else if (c >= 'A' && c <= 'F') - { - return c - 'A' + 10; - } - else - { - return -1; - } - } } #endif