mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Optimize TranslationMapping by using short, array and pre-allocated list
Saving about 60% memory (measured about 500K in production, depending on queries)
This commit is contained in:
parent
83883c4b05
commit
6f5a620495
3 changed files with 33 additions and 12 deletions
|
|
@ -119,7 +119,7 @@ namespace Flow.Launcher.Infrastructure
|
|||
{
|
||||
var resultList = WordsHelper.GetPinyinList(content);
|
||||
var resultBuilder = new StringBuilder(_settings.UseDoublePinyin ? 3 : 4); // Pre-allocate with estimated capacity
|
||||
var map = new TranslationMapping();
|
||||
var map = new TranslationMapping(resultList.Length);
|
||||
|
||||
var previousIsChinese = false;
|
||||
|
||||
|
|
@ -157,10 +157,7 @@ namespace Flow.Launcher.Infrastructure
|
|||
|
||||
map.EndConstruct();
|
||||
|
||||
var translation = resultBuilder.ToString();
|
||||
var result = (translation, map);
|
||||
|
||||
return _pinyinCache[content] = result;
|
||||
return _pinyinCache[content] = (resultBuilder.ToString(), map);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -9,18 +9,38 @@ namespace Flow.Launcher.Infrastructure
|
|||
|
||||
// Assuming one original item maps to multi translated items
|
||||
// list[i] is the last translated index + 1 of original index i
|
||||
private readonly List<int> _originalToTranslated = new();
|
||||
// Using short instead of int to save memory
|
||||
private List<short> _originalToTranslatedBuilder;
|
||||
private short[] _originalToTranslated;
|
||||
|
||||
public TranslationMapping(int capacityHint = 16)
|
||||
{
|
||||
_originalToTranslatedBuilder = new List<short>(capacityHint);
|
||||
}
|
||||
|
||||
public void AddNewIndex(int translatedIndex, int length)
|
||||
{
|
||||
if (_isConstructed)
|
||||
throw new InvalidOperationException("Mapping shouldn't be changed after construction");
|
||||
_originalToTranslated.Add(translatedIndex + length);
|
||||
|
||||
var value = translatedIndex + length;
|
||||
if (value > short.MaxValue)
|
||||
throw new ArgumentOutOfRangeException(nameof(translatedIndex),
|
||||
"Translation index exceeds maximum supported value (32,767)");
|
||||
|
||||
_originalToTranslatedBuilder.Add((short)value);
|
||||
}
|
||||
|
||||
public int MapToOriginalIndex(int translatedIndex)
|
||||
{
|
||||
var searchResult = _originalToTranslated.BinarySearch(translatedIndex);
|
||||
if (_originalToTranslated == null)
|
||||
throw new InvalidOperationException("Mapping must be constructed before use");
|
||||
|
||||
if (translatedIndex > short.MaxValue)
|
||||
throw new ArgumentOutOfRangeException(nameof(translatedIndex),
|
||||
"Translation index exceeds maximum supported value (32,767)");
|
||||
|
||||
var searchResult = Array.BinarySearch(_originalToTranslated, (short)translatedIndex);
|
||||
return searchResult >= 0 ? searchResult + 1 : ~searchResult;
|
||||
}
|
||||
|
||||
|
|
@ -28,6 +48,10 @@ namespace Flow.Launcher.Infrastructure
|
|||
{
|
||||
if (_isConstructed)
|
||||
throw new InvalidOperationException("Mapping has already been constructed");
|
||||
|
||||
// Convert to array to save memory (no List overhead, no excess capacity)
|
||||
_originalToTranslated = _originalToTranslatedBuilder.ToArray();
|
||||
_originalToTranslatedBuilder = null; // Allow GC to collect the List
|
||||
_isConstructed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,15 +57,15 @@ namespace Flow.Launcher.Test
|
|||
private static int GetOriginalToTranslatedCount(TranslationMapping mapping)
|
||||
{
|
||||
var field = typeof(TranslationMapping).GetField("_originalToTranslated", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var list = (List<int>)field.GetValue(mapping);
|
||||
return list.Count;
|
||||
var array = (short[])field.GetValue(mapping);
|
||||
return array.Length;
|
||||
}
|
||||
|
||||
private static int GetOriginalToTranslatedAt(TranslationMapping mapping, int index)
|
||||
{
|
||||
var field = typeof(TranslationMapping).GetField("_originalToTranslated", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var list = (List<int>)field.GetValue(mapping);
|
||||
return list[index];
|
||||
var array = (short[])field.GetValue(mapping);
|
||||
return array[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue