Files
Terminal.Gui/Benchmarks/Text/StringExtensions/ToStringEnumerable.cs

85 lines
3.6 KiB
C#

using System.Text;
using BenchmarkDotNet.Attributes;
using Tui = Terminal.Gui;
namespace Terminal.Gui.Benchmarks.Text.StringExtensions;
/// <summary>
/// Benchmarks for <see cref="Tui.StringExtensions.ToString(IEnumerable{Rune})"/> performance fine-tuning.
/// </summary>
[MemoryDiagnoser]
public class ToStringEnumerable
{
/// <summary>
/// Benchmark for previous implementation.
/// </summary>
[Benchmark]
[ArgumentsSource (nameof (DataSource))]
public string Previous (IEnumerable<Rune> runes, int len)
{
return StringConcatInLoop (runes);
}
/// <summary>
/// Benchmark for current implementation with char buffer and
/// fallback to rune chars appending to StringBuilder.
/// </summary>
/// <param name="runes"></param>
/// <returns></returns>
[Benchmark (Baseline = true)]
[ArgumentsSource (nameof (DataSource))]
public string Current (IEnumerable<Rune> runes, int len)
{
return Tui.StringExtensions.ToString (runes);
}
/// <summary>
/// Previous implementation with string concatenation in a loop.
/// </summary>
private static string StringConcatInLoop (IEnumerable<Rune> runes)
{
var str = string.Empty;
foreach (Rune rune in runes)
{
str += rune.ToString ();
}
return str;
}
public IEnumerable<object []> DataSource ()
{
// Extra length argument as workaround for the summary grouping
// different length collections to same baseline making comparison difficult.
foreach (string text in GetTextData ())
{
Rune [] runes = [..text.EnumerateRunes ()];
yield return [runes, runes.Length];
}
}
private IEnumerable<string> GetTextData ()
{
string textSource =
"""
Ĺόŕéḿ íśúḿ d́όĺόŕ śí áḿé, ćόńśéćt́ét́úŕ ád́íṕíśćíńǵ éĺí. ŕáéśéń q́úíś ĺúćt́úś éĺí. Íńt́éǵéŕ ú áŕćú éǵé d́όĺόŕ śćéĺéŕíśq́úé ḿát́t́íś áć é d́íáḿ.
éĺĺéńt́éśq́úé śé d́áṕíb́úś ḿáśśá, v́éĺ t́ŕíśt́íq́úé d́úí. Śéd́ v́ít́áé ńéq́úé éú v́éĺít́ όŕńáŕé áĺíq́úét́. Ú q́úíś όŕćí t́éḿṕόŕ, t́éḿṕόŕ t́úŕṕíś í, t́éḿṕúś ńéq́úé.
ŕáéśéń śáíéń t́úŕṕíś, όŕńáŕé v́éĺ ḿáúŕíś á, v́áŕíúś śúśćíí áńt́é. Ú úĺv́íńáŕ t́úŕṕíś ḿáśśá, q́úíś ćúŕśúś áŕćú f́áúćíb́úś íń.
Óŕćí v́áŕíúś ńát́όq́úé éńát́íb́úś é ḿáǵńíś d́íś áŕt́úŕíéńt́ ḿόńt́éś, ńáśćét́úŕ ŕíd́íćúĺúś ḿúś. F́úśćé á é b́ĺáńd́ít́, ćόńv́áĺĺíś q́úáḿ é, v́úĺṕút́át́é ĺáćúś.
Śúśṕéńd́íśśé śí áḿé áŕćú ú áŕćú f́áúćíb́úś v́áŕíúś. V́ív́áḿúś śí áḿé ḿáx́íḿúś d́íáḿ. Ńáḿ é ĺéό, h́áŕét́ŕá éú ĺόb́όŕt́íś á, t́ŕíśt́íq́úé ú f́éĺíś.
""";
int[] lengths = [1, 10, 100, textSource.Length / 2, textSource.Length];
foreach (int length in lengths)
{
yield return textSource [..length];
}
string textLongerThanStackallocThreshold = string.Concat(Enumerable.Repeat(textSource, 10));
yield return textLongerThanStackallocThreshold;
}
}