using System.Text;
using BenchmarkDotNet.Attributes;
using Tui = Terminal.Gui;
namespace Terminal.Gui.Benchmarks.Text.RuneExtensions;
///
/// Benchmarks for performance fine-tuning.
///
[MemoryDiagnoser]
[BenchmarkCategory (nameof (Tui.RuneExtensions))]
public class DecodeSurrogatePair
{
///
/// Benchmark for previous implementation.
///
///
///
[Benchmark]
[ArgumentsSource (nameof (DataSource))]
public char []? Previous (Rune rune)
{
_ = RuneToStringToCharArray (rune, out char []? chars);
return chars;
}
///
/// Benchmark for current implementation.
///
/// Utilizes Rune methods that take Span argument avoiding intermediate heap array allocation when combined with stack allocated intermediate buffer.
/// When rune is not surrogate pair there will be no heap allocation.
///
/// Final surrogate pair array allocation cannot be avoided due to the current method signature design.
/// Changing the method signature, or providing an alternative method, to take a destination Span would allow further optimizations by allowing caller to reuse buffer for consecutive calls.
///
[Benchmark (Baseline = true)]
[ArgumentsSource (nameof (DataSource))]
public char []? Current (Rune rune)
{
_ = Tui.RuneExtensions.DecodeSurrogatePair (rune, out char []? chars);
return chars;
}
///
/// Previous implementation with intermediate string allocation.
///
/// The IsSurrogatePair implementation at the time had hidden extra string allocation so there were intermediate heap allocations even if rune is not surrogate pair.
///
private static bool RuneToStringToCharArray (Rune rune, out char []? chars)
{
if (rune.IsSurrogatePair ())
{
chars = rune.ToString ().ToCharArray ();
return true;
}
chars = null;
return false;
}
public static IEnumerable