Refactor: outline single-byte buffer grow for hot path

Refactored WriteByte, WriteVarUInt, and WriteVarULong to use a new GrowOne helper for single-byte buffer growth. This moves the Output.Grow call out of the hot path, improving inlining and serialization performance for frequent single-byte writes. Added detailed comments explaining the rationale and AOT benefits.
This commit is contained in:
Loretta 2026-05-13 20:01:11 +02:00
parent 72dab46bde
commit b849beb2ee
1 changed files with 14 additions and 6 deletions

View File

@ -388,11 +388,21 @@ public static partial class AcBinarySerializer
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteByte(byte value)
{
if (_position >= _bufferEnd)
Output.Grow(ref _buffer, ref _position, ref _bufferEnd, 1);
if (_position >= _bufferEnd) GrowOne();
_buffer[_position++] = value;
}
/// <summary>
/// Cold-path single-byte grow helper. Outlined from the hot-path 1-byte writers
/// (<see cref="WriteByte"/>, <see cref="WriteVarUInt"/> / <see cref="WriteVarULong"/> fast-paths)
/// so the inliner cost-models the hot path WITHOUT the 4-ref-arg <c>Output.Grow</c> call's
/// argument-prep IL. This keeps the per-property hot-path tight enough for AOT to inline the
/// write into the source-gen <c>WriteProperties</c> body across many call-sites — the cumulative
/// gain shows up on graph-heavy cells where every leaf serialises ~6 primitive properties.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
private void GrowOne() => Output.Grow(ref _buffer, ref _position, ref _bufferEnd, 1);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteTwoBytes(byte b1, byte b2)
{
@ -464,8 +474,7 @@ public static partial class AcBinarySerializer
//if (FastWire) { WriteRaw(value); return; }
if (value < 0x80)
{
if (_position >= _bufferEnd)
Output.Grow(ref _buffer, ref _position, ref _bufferEnd, 1);
if (_position >= _bufferEnd) GrowOne();
_buffer[_position++] = (byte)value;
return;
}
@ -531,8 +540,7 @@ public static partial class AcBinarySerializer
//if (FastWire) { WriteRaw(value); return; }
if (value < 0x80)
{
if (_position >= _bufferEnd)
Output.Grow(ref _buffer, ref _position, ref _bufferEnd, 1);
if (_position >= _bufferEnd) GrowOne();
_buffer[_position++] = (byte)value;
return;
}