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
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -29,6 +48,13 @@ internal static class Cell
|
||||
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