diff --git a/Benchmarks/Text/StringExtensions/ToStringEnumerable.cs b/Benchmarks/Text/StringExtensions/ToStringEnumerable.cs index 8d5d55f41..b44f33ad5 100644 --- a/Benchmarks/Text/StringExtensions/ToStringEnumerable.cs +++ b/Benchmarks/Text/StringExtensions/ToStringEnumerable.cs @@ -22,7 +22,7 @@ public class ToStringEnumerable } /// - /// Benchmark for current implementation with stackalloc char buffer and + /// Benchmark for current implementation with char buffer and /// fallback to rune chars appending to StringBuilder. /// /// diff --git a/Terminal.Gui/Text/StringExtensions.cs b/Terminal.Gui/Text/StringExtensions.cs index 3167bcf30..0dc1acdec 100644 --- a/Terminal.Gui/Text/StringExtensions.cs +++ b/Terminal.Gui/Text/StringExtensions.cs @@ -127,7 +127,7 @@ public static class StringExtensions const int maxCharsPerRune = 2; const int maxStackallocTextBufferSize = 1048; // ~2 kB - // Use stackalloc buffer if rune count is easily available and the count is reasonable. + // If rune count is easily available use stackalloc buffer or alternatively rented array. if (runes.TryGetNonEnumeratedCount (out int count)) { if (count == 0) @@ -135,10 +135,14 @@ public static class StringExtensions return string.Empty; } - int maxRequiredTextBufferSize = count * maxCharsPerRune; - if (maxRequiredTextBufferSize <= maxStackallocTextBufferSize) + char[]? rentedBufferArray = null; + try { - Span textBuffer = stackalloc char[maxRequiredTextBufferSize]; + int maxRequiredTextBufferSize = count * maxCharsPerRune; + Span textBuffer = maxRequiredTextBufferSize <= maxStackallocTextBufferSize + ? stackalloc char[maxRequiredTextBufferSize] + : (rentedBufferArray = ArrayPool.Shared.Rent(maxRequiredTextBufferSize)); + Span remainingBuffer = textBuffer; foreach (Rune rune in runes) { @@ -149,6 +153,13 @@ public static class StringExtensions ReadOnlySpan text = textBuffer[..^remainingBuffer.Length]; return text.ToString (); } + finally + { + if (rentedBufferArray != null) + { + ArrayPool.Shared.Return (rentedBufferArray); + } + } } // Fallback to StringBuilder append.