[LOADED_DOCS: 2 files, no new loads]
Optimize FastWire string (de)serialization and benchmarks - Increased release benchmark iterations for more robust testing. - Improved FastWire string deserialization with zero-copy UTF-16. - Set FastWire and string caching options during context init/reset. - Optimized FastWire string serialization for direct UTF-16 copy. - Enhanced non-ASCII string fallback to use Utf8NoBom encoding. - Refactored WriteFixStr for efficient ASCII and fallback handling.
This commit is contained in:
parent
80235c9a3d
commit
2c73775389
|
|
@ -45,8 +45,8 @@ public static class Program
|
|||
private static int TestIterations = 1;
|
||||
private static int BenchmarkSamples = 1; // Debug: single sample, fast iteration
|
||||
#else
|
||||
private static int WarmupIterations = 100; //5000
|
||||
private static int TestIterations = 10; //1000
|
||||
private static int WarmupIterations = 5000; //5000
|
||||
private static int TestIterations = 1000; //1000
|
||||
private static int BenchmarkSamples = 3;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -365,8 +365,10 @@ public static partial class AcBinaryDeserializer
|
|||
{
|
||||
var byteLen = length * 2;
|
||||
EnsureAvailable(byteLen);
|
||||
|
||||
var chars = MemoryMarshal.Cast<byte, char>(_buffer.AsSpan(_position, byteLen));
|
||||
var value = new string(chars);
|
||||
|
||||
_position += byteLen;
|
||||
return value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,13 +152,17 @@ public static partial class AcBinaryDeserializer
|
|||
{
|
||||
Input = input;
|
||||
Input.Initialize(out _buffer, out _position, out _bufferLength);
|
||||
|
||||
_useStringCaching = Options.UseStringCaching;
|
||||
_maxCachedStringLength = Options.MaxCachedStringLength;
|
||||
|
||||
if (_useStringCaching) GetOrCreateStringCache();
|
||||
|
||||
_internCache = null;
|
||||
HasMetadata = false;
|
||||
IsMergeMode = false;
|
||||
RemoveOrphanedItems = false;
|
||||
|
||||
FastWire = Options.WireMode == WireMode.Fast;
|
||||
ChainTracker = null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,9 +290,12 @@ public static partial class AcBinarySerializer
|
|||
{
|
||||
// IMPORTANT: base.Reset sets Options first, so derived code can use Options-derived properties
|
||||
base.Reset(options);
|
||||
|
||||
HasPropertyFilter = Options.PropertyFilter != null;
|
||||
|
||||
InternBit = 1 << (int)Options.UseStringInterning;
|
||||
HasStringInterning = Options.UseStringInterning != StringInterningMode.None;
|
||||
|
||||
FastWire = Options.WireMode == WireMode.Fast;
|
||||
}
|
||||
|
||||
|
|
@ -658,10 +661,13 @@ public static partial class AcBinarySerializer
|
|||
// UTF-16: char count (VarUInt) + raw char data (zero-encoding memcopy)
|
||||
var charLen = value.Length;
|
||||
var byteLen = charLen * 2;
|
||||
|
||||
WriteVarUInt((uint)charLen);
|
||||
EnsureCapacity(byteLen);
|
||||
|
||||
MemoryMarshal.AsBytes(value.AsSpan()).CopyTo(_buffer.AsSpan(_position, byteLen));
|
||||
_position += byteLen;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -681,9 +687,11 @@ public static partial class AcBinarySerializer
|
|||
|
||||
// Non-ASCII fallback: safe rewind (no Grow happened since pre-allocate)
|
||||
_position = savedPosition;
|
||||
|
||||
var byteCount = Utf8NoBom.GetByteCount(value);
|
||||
EnsureCapacity(VarUIntSize((uint)byteCount) + byteCount);
|
||||
WriteVarUIntUnsafe((uint)byteCount);
|
||||
|
||||
Utf8NoBom.GetBytes(value.AsSpan(), _buffer.AsSpan(_position, byteCount));
|
||||
_position += byteCount;
|
||||
}
|
||||
|
|
@ -699,25 +707,21 @@ public static partial class AcBinarySerializer
|
|||
|
||||
public void WriteFixStrDirect(string value)
|
||||
{
|
||||
// Compute UTF-8 byte count up front. FixStr opcode encodes byte count (5-bit field, ≤31).
|
||||
// For ASCII: byte count = char count; for non-ASCII: byte count > char count.
|
||||
// Bonus over the prior ASCII-only path: short non-ASCII strings (e.g. 8-char Hungarian
|
||||
// ≈ 12 bytes) now also fit in FixStr and save the String-marker + VarUInt overhead.
|
||||
var byteCount = Utf8NoBom.GetByteCount(value);
|
||||
if (byteCount <= BinaryTypeCode.FixStrMaxLength)
|
||||
var length = value.Length;
|
||||
EnsureCapacity(1 + length);
|
||||
|
||||
var destSpan = _buffer.AsSpan(_position + 1, length);
|
||||
var status = Ascii.FromUtf16(value.AsSpan(), destSpan, out var bytesWritten);
|
||||
|
||||
if (status == OperationStatus.Done && bytesWritten == length)
|
||||
{
|
||||
EnsureCapacity(1 + byteCount);
|
||||
_buffer[_position++] = BinaryTypeCode.EncodeFixStr(byteCount);
|
||||
Utf8NoBom.GetBytes(value.AsSpan(), _buffer.AsSpan(_position, byteCount));
|
||||
_position += byteCount;
|
||||
_buffer[_position] = BinaryTypeCode.EncodeFixStr(length);
|
||||
_position += 1 + length;
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer[_position++] = BinaryTypeCode.String;
|
||||
EnsureCapacity(VarUIntSize((uint)byteCount) + byteCount);
|
||||
WriteVarUIntUnsafe((uint)byteCount);
|
||||
Utf8NoBom.GetBytes(value.AsSpan(), _buffer.AsSpan(_position, byteCount));
|
||||
_position += byteCount;
|
||||
WriteStringUtf8Internal(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue