Skip to content

Commit 8aba1f2

Browse files
authored
Reduce allocations in ChecksumUtilities.BytesToString (#12359)
* Reduce allocations in ChecksumUtilities.BytesToString This method was previously allocating a string for each byte being converted and then allocating another string for the stringbuilder.ToString call. Instead: if >NET9 use Convert.ToHexStringLower else create stack alloc'ed char[] and put converted chars in there and allocate a single string from that
1 parent 90444a4 commit 8aba1f2

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/ChecksumUtilities.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
using System;
55
using System.Collections.Immutable;
6-
using System.Globalization;
7-
using Microsoft.AspNetCore.Razor.PooledObjects;
86

97
namespace Microsoft.AspNetCore.Razor.Language;
108

@@ -17,15 +15,22 @@ public static string BytesToString(ImmutableArray<byte> bytes)
1715
throw new ArgumentNullException(nameof(bytes));
1816
}
1917

20-
using var _ = StringBuilderPool.GetPooledObject(out var builder);
21-
builder.EnsureCapacity(bytes.Length);
22-
23-
foreach (var b in bytes)
18+
#if NET9_0_OR_GREATER
19+
return Convert.ToHexStringLower(bytes.AsSpan());
20+
#else
21+
return string.Create(bytes.Length * 2, bytes, static (span, bytes) =>
2422
{
25-
// The x2 format means lowercase hex, where each byte is a 2-character string.
26-
builder.Append(b.ToString("x2", CultureInfo.InvariantCulture));
27-
}
23+
foreach (var b in bytes)
24+
{
25+
// Write hex chars directly
26+
span[0] = GetHexChar(b >> 4);
27+
span[1] = GetHexChar(b & 0xf);
28+
span = span[2..];
29+
}
30+
});
2831

29-
return builder.ToString();
32+
static char GetHexChar(int value)
33+
=> (char)(value < 10 ? '0' + value : 'a' + (value - 10));
34+
#endif
3035
}
3136
}

0 commit comments

Comments
 (0)