fix: Eliminates string allocations while writing gump packets (#1017)

* Introduces `RawInterpolatedStringHandler` which is exactly the same as `DefaultInterpolatedStringHandler` except it _unsafely exposes_ it's `ReadOnlySpan<char>` buffer. This is useful for writing the string's data without actually building the string.
* Uses this new string interpolation handler in `SpanWriter` to eliminate intermediate strings built. This is immensely useful in eliminating string allocations in writing Gump packets.
This commit is contained in:
Kamron Batman 2022-05-10 18:50:23 -07:00 • committed by GitHub
parent f7cbeacf48
commit 87b63b38a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 674 additions and 43 deletions

View file

@ -137,7 +137,7 @@ public class LocalizationEntry
public LocalizationInterpolationHandler(int literalLength, int formattedCount, LocalizationEntry entry, out bool isValid)
{
_slices = entry.TextSlices;
_chars = _arrayToReturnToPool = ArrayPool<char>.Shared.Rent(256);
_chars = _arrayToReturnToPool = STArrayPool<char>.Shared.Rent(256);
isValid = true;
_pos = 0;
@ -159,7 +159,7 @@ public class LocalizationEntry
if (Localization.TryGetLocalization(lang, number, out var entry))
{
_slices = entry.TextSlices;
_chars = _arrayToReturnToPool = ArrayPool<char>.Shared.Rent(256);
_chars = _arrayToReturnToPool = STArrayPool<char>.Shared.Rent(256);
isValid = true;
}
else
@ -509,10 +509,10 @@ public class LocalizationEntry
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void GrowCore(uint requiredMinCapacity)
{
var newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, 1073741823));
var newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, 0x3FFFFFDF));
var arraySize = (int)Math.Clamp(newCapacity, 256, int.MaxValue);
var newArray = ArrayPool<char>.Shared.Rent(arraySize);
var newArray = STArrayPool<char>.Shared.Rent(arraySize);
_chars[.._pos].CopyTo(newArray);
var toReturn = _arrayToReturnToPool;
@ -520,7 +520,7 @@ public class LocalizationEntry
if (toReturn is not null)
{
ArrayPool<char>.Shared.Return(toReturn);
STArrayPool<char>.Shared.Return(toReturn);
}
}
@ -533,7 +533,7 @@ public class LocalizationEntry
this = default; // defensive clear
if (toReturn is not null)
{
ArrayPool<char>.Shared.Return(toReturn);
STArrayPool<char>.Shared.Return(toReturn);
}
}