mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-07-04 19:58:14 +08:00
Reduce memory usage for rune width cache. (#1756)
This commit is contained in:
@ -2,7 +2,26 @@ namespace Spectre.Console;
|
|||||||
|
|
||||||
internal static class Cell
|
internal static class Cell
|
||||||
{
|
{
|
||||||
private static readonly int?[] _runeWidthCache = new int?[char.MaxValue];
|
private const sbyte Sentinel = -2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// UnicodeCalculator.GetWidth documents the width as (-1, 0, 1, 2). We only need space for these values and a sentinel for uninitialized values.
|
||||||
|
/// This is only five values in total so we are storing one byte per value. We could store 2 per byte but that would add more logic to the retrieval.
|
||||||
|
/// We should add one to char.MaxValue because the total number of characters includes \0 too so there are 65536 valid chars.
|
||||||
|
/// </summary>
|
||||||
|
private static readonly sbyte[] _runeWidthCache = new sbyte[char.MaxValue + 1];
|
||||||
|
|
||||||
|
static Cell()
|
||||||
|
{
|
||||||
|
#if !NETSTANDARD2_0
|
||||||
|
Array.Fill(_runeWidthCache, Sentinel);
|
||||||
|
#else
|
||||||
|
for (var i = 0; i < _runeWidthCache.Length; i++)
|
||||||
|
{
|
||||||
|
_runeWidthCache[i] = Sentinel;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
public static int GetCellLength(string text)
|
public static int GetCellLength(string text)
|
||||||
{
|
{
|
||||||
@ -29,6 +48,13 @@ internal static class Cell
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _runeWidthCache[rune] ??= UnicodeCalculator.GetWidth(rune);
|
var width = _runeWidthCache[rune];
|
||||||
|
if (width == Sentinel)
|
||||||
|
{
|
||||||
|
_runeWidthCache[rune] = (sbyte)UnicodeCalculator.GetWidth(rune);
|
||||||
|
return _runeWidthCache[rune];
|
||||||
|
}
|
||||||
|
|
||||||
|
return _runeWidthCache[rune];
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user