Skip to content

Commit

Permalink
ConversionPresetHelper: Reduce char[] allocation overhead.
Browse files Browse the repository at this point in the history
Merge char segments into a large pool.
  • Loading branch information
CXuesong committed Feb 22, 2022
1 parent 0e56b14 commit 6152774
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions OpenCCSharp.Presets/ConversionPresetHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,43 @@ static async Task<TrieStringPrefixDictionary> ValueFactory(string fn, Concurrent
if (rs == null)
throw new MissingManifestResourceException($"Failed to retrieve the manifest resource: {resourceName}.");

// Merge small char arrays into large char pools to reduce 16B per object overhead.
var charPool = GC.AllocateUninitializedArray<char>(Math.Clamp((int)(rs.Length / 8), 32, 512 * 1024));
var charPoolPos = 0;
var charPoolLengthSum = charPool.Length;
Memory<char> AllocateCharPoolMemory(int size)
{
if (charPool.Length - charPoolPos < size)
{
// Note that StreamReader in EnumEntriesFromAsync has its own buffer...
var readerPosGuess = rs.Position >= rs.Length ? Math.Max(0, rs.Length - 256) : Math.Max(0, rs.Position - 512);
// Estimate how large the next pool should be.
charPool = GC.AllocateUninitializedArray<char>(Math.Clamp(
(int)((float)charPoolLengthSum / readerPosGuess * (rs.Length - readerPosGuess)),
Math.Max(64, size), 512 * 1024));
charPoolLengthSum += charPool.Length;
charPoolPos = 0;
}
var m = charPool.AsMemory(charPoolPos, size);
charPoolPos += size;
return m;
}
await foreach (var (k, v) in PlainTextConversionLookupTable.EnumEntriesFromAsync(rs))
{
if (reverse)
{
foreach (var v1 in v) dict.TryAdd(v1, k.ToArray());
foreach (var v1 in v)
{
var m = AllocateCharPoolMemory(k.Length);
k.CopyTo(m);
dict.TryAdd(v1, m);
}
}
else
{
dict.TryAdd(k, v[0].ToArray());
var m = AllocateCharPoolMemory(v[0].Length);
v[0].CopyTo(m);
dict.TryAdd(k, m);
}
}
}
Expand Down

0 comments on commit 6152774

Please sign in to comment.