CommunityToolkit / dotnet

.NET Community Toolkit is a collection of helpers and APIs that work for all .NET developers and are agnostic of any specific UI platform. The toolkit is maintained and published by Microsoft, and part of the .NET Foundation.
https://docs.microsoft.com/dotnet/communitytoolkit/?WT.mc_id=dotnet-0000-bramin
Other
2.99k stars 294 forks source link

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

Open ovska opened 1 year ago

ovska commented 1 year ago

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.