dotnet icon indicating copy to clipboard operation
dotnet copied to clipboard

Perf: stackalloc on short inputs to StringPool.GetOrAdd(ReadOnlySpan<byte>, Encoding)

Open ovska opened this issue 2 years ago • 0 comments

Currently for all non-empty inputs an array is rented from the pool. My naive assumption is, however, that the pool is commonly used for shorter strings. I suggest stackalloc be used when GetMaxCharCount is small, e.g. 64 or 128.

public unsafe string GetOrAdd(ReadOnlySpan<byte> span, Encoding encoding)
{
    if (span.IsEmpty)
    {
        return string.Empty;
    }

+   if (maxLength <= 128)
+   {
+       Span<char> buffer = stackalloc char[maxLength];

+       fixed (byte* source = span)
+       fixed (char* destination = &buffer.DangerousGetReference())
+       {
+           int effectiveLength = encoding.GetChars(source, span.Length, destination, maxLength);
+
+           return GetOrAdd(new ReadOnlySpan<char>(destination, effectiveLength));
+       }
+   }
+   else
+   {
        using SpanOwner<char> buffer = SpanOwner<char>.Allocate(maxLength);

        fixed (byte* source = span)
        fixed (char* destination = &buffer.DangerousGetReference())
        {
            int effectiveLength = encoding.GetChars(source, span.Length, destination, maxLength);

            return GetOrAdd(new ReadOnlySpan<char>(destination, effectiveLength));
        }
+   }
} 

Issue submitted without a template as this isn't an API request or a bug report.

ovska avatar May 15 '23 06:05 ovska