Enable FastWire mode for binary string serialization
Activate FastWire encoding for both serialization and deserialization, using UTF-16 and fixed-width lengths for strings. WireMode is now public and defaults to FastWire. Removes unused ObjectEnd marker, clarifying object end handling. This improves string (de)serialization speed at the cost of larger output.
This commit is contained in:
parent
a1a2a90ef7
commit
bbed1caf44
|
|
@ -330,15 +330,15 @@ public static partial class AcBinaryDeserializer
|
|||
}
|
||||
|
||||
// FastWire: length is char count, data is UTF-16 (2 bytes per char)
|
||||
//if (FastWire)
|
||||
//{
|
||||
// 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;
|
||||
//}
|
||||
if (FastWire)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
EnsureAvailable(length);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public static partial class AcBinaryDeserializer
|
|||
public bool HasMetadata;
|
||||
public bool IsMergeMode;
|
||||
public bool RemoveOrphanedItems;
|
||||
//public bool FastWire;
|
||||
public bool FastWire;
|
||||
|
||||
// Options-derived properties
|
||||
public byte MinStringInternLength => Options.MinStringInternLength;
|
||||
|
|
@ -139,7 +139,7 @@ public static partial class AcBinaryDeserializer
|
|||
HasMetadata = false;
|
||||
IsMergeMode = false;
|
||||
RemoveOrphanedItems = false;
|
||||
//FastWire = Options.WireMode == WireMode.Fast;
|
||||
FastWire = Options.WireMode == WireMode.Fast;
|
||||
ChainTracker = null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ public static partial class AcBinarySerializer
|
|||
/// Reference handling is safe because generated code inlines TryConsumeWritePlanEntry for IId types.
|
||||
/// </summary>
|
||||
public bool IsDirectObjectWrite => !UseMetadata;
|
||||
//public bool FastWire { get; private set; }
|
||||
public bool FastWire { get; private set; }
|
||||
public byte MinStringInternLength => Options.MinStringInternLength;
|
||||
public byte MaxStringInternLength => Options.MaxStringInternLength;
|
||||
public BinaryPropertyFilter? PropertyFilter => Options.PropertyFilter;
|
||||
|
|
@ -281,7 +281,7 @@ public static partial class AcBinarySerializer
|
|||
HasPropertyFilter = Options.PropertyFilter != null;
|
||||
InternBit = 1 << (int)Options.UseStringInterning;
|
||||
HasStringInterning = Options.UseStringInterning != StringInterningMode.None;
|
||||
//FastWire = Options.WireMode == WireMode.Fast;
|
||||
FastWire = Options.WireMode == WireMode.Fast;
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
|
|
@ -630,17 +630,17 @@ public static partial class AcBinarySerializer
|
|||
|
||||
public void WriteStringUtf8(string value)
|
||||
{
|
||||
//if (FastWire)
|
||||
//{
|
||||
// // UTF-16: char count (fixed uint) + raw char data (zero-encoding memcopy)
|
||||
// var charLen = value.Length;
|
||||
// var byteLen = charLen * 2;
|
||||
// WriteRaw(charLen);
|
||||
// EnsureCapacity(byteLen);
|
||||
// MemoryMarshal.AsBytes(value.AsSpan()).CopyTo(_buffer.AsSpan(_position, byteLen));
|
||||
// _position += byteLen;
|
||||
// return;
|
||||
//}
|
||||
if (FastWire)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
var charLength = value.Length;
|
||||
|
||||
|
|
|
|||
|
|
@ -1023,12 +1023,12 @@ public static partial class AcBinarySerializer
|
|||
}
|
||||
|
||||
// FastWire: skip FixStr optimization (UTF-8 specific), write String marker + UTF-16 data
|
||||
//if (context.FastWire)
|
||||
//{
|
||||
// context.WriteByte(BinaryTypeCode.String);
|
||||
// context.WriteStringUtf8(value);
|
||||
// return;
|
||||
//}
|
||||
if (context.FastWire)
|
||||
{
|
||||
context.WriteByte(BinaryTypeCode.String);
|
||||
context.WriteStringUtf8(value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fast path for short strings: check length first (cheap), then ASCII
|
||||
// FixStr encodes type+length in single byte for strings <= 31 chars
|
||||
|
|
|
|||
|
|
@ -85,6 +85,13 @@ public sealed class AcBinarySerializerOptions : AcSerializerOptions
|
|||
public bool UseMetadata { get; set; } = false;
|
||||
public bool UseGeneratedCode { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Wire encoding mode.
|
||||
/// Compact: VarInt + UTF-8 (default, smaller output).
|
||||
/// Fast: Fixed-width integers + UTF-16 (larger output, faster encode/decode).
|
||||
/// </summary>
|
||||
public WireMode WireMode { get; set; } = WireMode.Fast;
|
||||
|
||||
/// <summary>
|
||||
/// Controls how string interning is applied during serialization.
|
||||
/// None: No interning, all strings written inline.
|
||||
|
|
@ -94,13 +101,6 @@ public sealed class AcBinarySerializerOptions : AcSerializerOptions
|
|||
/// </summary>
|
||||
public StringInterningMode UseStringInterning { get; set; } = StringInterningMode.Attribute;
|
||||
|
||||
/// <summary>
|
||||
/// Wire encoding mode.
|
||||
/// Compact: VarInt + UTF-8 (default, smaller output).
|
||||
/// Fast: Fixed-width integers + UTF-16 (larger output, faster encode/decode).
|
||||
/// </summary>
|
||||
//public WireMode WireMode { get; set; } = WireMode.Compact;
|
||||
|
||||
/// <summary>
|
||||
/// When true, checks for duplicate property name hashes during serialization (UseMetadata mode).
|
||||
/// Throws exception if FNV-1a hash collision is detected between property names of the same type.
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ internal static class BinaryTypeCode
|
|||
|
||||
// Complex types (25-31)
|
||||
public const byte Object = 25; // Start of object (non-tracked OR first occurrence when ref tracking)
|
||||
public const byte ObjectEnd = 26; // End of object marker
|
||||
//public const byte ObjectEnd = 26; // UNUSED — property count is known at compile-time (SGen) or reflection-time (runtime), no end marker needed
|
||||
public const byte ObjectRef = 27; // Reference to previously serialized object (2+ occurrence)
|
||||
public const byte Array = 28; // Start of array/list
|
||||
public const byte Dictionary = 29; // Start of dictionary
|
||||
|
|
|
|||
Loading…
Reference in New Issue