mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* touching publish.yml * Moved Examples into ./Examples * Moved Benchmarks into ./Tests * Moved Benchmarks into ./Tests * Moved UICatalog into ./Examples * Moved UICatalog into ./Examples 2 * Moved tests into ./Tests * Updated nuget
67 lines
2.2 KiB
C#
67 lines
2.2 KiB
C#
using System.Text;
|
||
using BenchmarkDotNet.Attributes;
|
||
using Tui = Terminal.Gui;
|
||
|
||
namespace Terminal.Gui.Benchmarks.Text.RuneExtensions;
|
||
|
||
/// <summary>
|
||
/// Benchmarks for <see cref="Tui.RuneExtensions.DecodeSurrogatePair"/> performance fine-tuning.
|
||
/// </summary>
|
||
[MemoryDiagnoser]
|
||
[BenchmarkCategory (nameof (Tui.RuneExtensions))]
|
||
public class DecodeSurrogatePair
|
||
{
|
||
/// <summary>
|
||
/// Benchmark for previous implementation.
|
||
/// </summary>
|
||
/// <param name="rune"></param>
|
||
/// <returns></returns>
|
||
[Benchmark]
|
||
[ArgumentsSource (nameof (DataSource))]
|
||
public char []? Previous (Rune rune)
|
||
{
|
||
_ = RuneToStringToCharArray (rune, out char []? chars);
|
||
return chars;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 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.
|
||
/// </summary>
|
||
[Benchmark (Baseline = true)]
|
||
[ArgumentsSource (nameof (DataSource))]
|
||
public char []? Current (Rune rune)
|
||
{
|
||
_ = Tui.RuneExtensions.DecodeSurrogatePair (rune, out char []? chars);
|
||
return chars;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 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.
|
||
/// </summary>
|
||
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<object> DataSource ()
|
||
{
|
||
yield return new Rune ('a');
|
||
yield return "𝔹".EnumerateRunes ().Single ();
|
||
}
|
||
}
|