- A high-performance string pooling library based on .NET9's
ArrayPooldesign, optimized for reusing string instances. - Reduces memory allocations and GC pressure by efficiently managing string lifetimes in performance-sensitive scenarios.
- ✅ GC Optimization: Minimizes string allocations by reusing pooled instances.
- ✅ Thread-Safe: Supports concurrent operations for multithreaded applications.
- ✅ Lightweight: Low-overhead design with minimal runtime impact.
- ✅ Seamless Integration: Simple API to replace ad-hoc string caching or frequent allocations.
- Frequent short-lived string allocations can degrade performance in high-throughput applications.
- Existing solutions like
ArrayPoolor manual caching lack dedicated support for string pooling. StringPoolprovides a standardized, efficient way to manage reusable strings without GC overhead.
-
public string Rent(int minimumLength)- Rent a string with at least the specified length from the pool.
-
public void Return(string array, bool clearArray = true)- Return a string to the pool,
- when
clearArrayis true (default), the string will be zeroed.
-
public string Rent(ReadOnlySpan<char> buffer)- Rent a string with at least the specified buffer's length from the pool,
- and copies the content from the buffer.
-
public bool SetText(ReadOnlySpan<char> buffer)-
Rents a new internal buffer if the current buffer is
null; -
or resizes the internal buffer if the current buffer's capacity is insufficient.
-
Then copies characters from the provided
ReadOnlySpan<char> bufferinto the internal buffer, -
returns
trueif a new buffer was rented, -
returns
falseif no new buffer was rented.You can use
public static implicit operator string?(UnsafeString? @string)to convert anUnsafeStringto astring, -
the string's
Lengthwill be equal tobuffer.Length.
-
-
public void Dispose()- Resets the internal string and returns it to the pool,
- then sets the internal string to
null.
-
You can use:
-
public static unsafe void Custom(Func<double> getMemoryPressure) -
public static unsafe void Custom(nint getMemoryPressure) -
public static unsafe void Custom(delegate* managed<double> getMemoryPressure)
to customize how
StringPooldetermines memory pressure for its automaticTrim()behavior.< 0.7-> low[0.7, 0.9)-> medium>= 0.9-> high
-
-
You can use:
public static void Configure(int DOTNET_SYSTEM_BUFFERS_SHAREDSTRINGPOOL_MAXSTRINGSPERPARTITION = 256, int DOTNET_SYSTEM_BUFFERS_SHAREDSTRINGPOOL_MAXPARTITIONCOUNT = int.MaxValue)
to pre-configure the
StringPool.Sharedparameters before initialization.DOTNET_SYSTEM_BUFFERS_SHAREDSTRINGPOOL_MAXSTRINGSPERPARTITION: Maximumstringsperpartition(default:256)DOTNET_SYSTEM_BUFFERS_SHAREDSTRINGPOOL_MAXPARTITIONCOUNT: Maximumpartitioncount (default:int.MaxValue, clamped toEnvironment.ProcessorCount)
⚠️ Has no effect afterStringPool.Sharedis initialized.
StringPool's Rent may not match the requested length.
- If you need the rented string’s actual length to equal the requested length,
- use
UnsafeString'spublic bool SetText(ReadOnlySpan<char> buffer), - and be sure to call
UnsafeString'spublic void Dispose().
string converted from UnsafeString:
- Does not guarantee the same lifetime or content consistency as the
UnsafeStringitself. - The safest practice is to update all
strings converted fromUnsafeStringevery time you update theUnsafeString.