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)
|
// FastWire: length is char count, data is UTF-16 (2 bytes per char)
|
||||||
//if (FastWire)
|
if (FastWire)
|
||||||
//{
|
{
|
||||||
// var byteLen = length * 2;
|
var byteLen = length * 2;
|
||||||
// EnsureAvailable(byteLen);
|
EnsureAvailable(byteLen);
|
||||||
// var chars = MemoryMarshal.Cast<byte, char>(_buffer.AsSpan(_position, byteLen));
|
var chars = MemoryMarshal.Cast<byte, char>(_buffer.AsSpan(_position, byteLen));
|
||||||
// var value = new string(chars);
|
var value = new string(chars);
|
||||||
// _position += byteLen;
|
_position += byteLen;
|
||||||
// return value;
|
return value;
|
||||||
//}
|
}
|
||||||
|
|
||||||
EnsureAvailable(length);
|
EnsureAvailable(length);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public static partial class AcBinaryDeserializer
|
||||||
public bool HasMetadata;
|
public bool HasMetadata;
|
||||||
public bool IsMergeMode;
|
public bool IsMergeMode;
|
||||||
public bool RemoveOrphanedItems;
|
public bool RemoveOrphanedItems;
|
||||||
//public bool FastWire;
|
public bool FastWire;
|
||||||
|
|
||||||
// Options-derived properties
|
// Options-derived properties
|
||||||
public byte MinStringInternLength => Options.MinStringInternLength;
|
public byte MinStringInternLength => Options.MinStringInternLength;
|
||||||
|
|
@ -139,7 +139,7 @@ public static partial class AcBinaryDeserializer
|
||||||
HasMetadata = false;
|
HasMetadata = false;
|
||||||
IsMergeMode = false;
|
IsMergeMode = false;
|
||||||
RemoveOrphanedItems = false;
|
RemoveOrphanedItems = false;
|
||||||
//FastWire = Options.WireMode == WireMode.Fast;
|
FastWire = Options.WireMode == WireMode.Fast;
|
||||||
ChainTracker = null;
|
ChainTracker = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ public static partial class AcBinarySerializer
|
||||||
/// Reference handling is safe because generated code inlines TryConsumeWritePlanEntry for IId types.
|
/// Reference handling is safe because generated code inlines TryConsumeWritePlanEntry for IId types.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsDirectObjectWrite => !UseMetadata;
|
public bool IsDirectObjectWrite => !UseMetadata;
|
||||||
//public bool FastWire { get; private set; }
|
public bool FastWire { get; private set; }
|
||||||
public byte MinStringInternLength => Options.MinStringInternLength;
|
public byte MinStringInternLength => Options.MinStringInternLength;
|
||||||
public byte MaxStringInternLength => Options.MaxStringInternLength;
|
public byte MaxStringInternLength => Options.MaxStringInternLength;
|
||||||
public BinaryPropertyFilter? PropertyFilter => Options.PropertyFilter;
|
public BinaryPropertyFilter? PropertyFilter => Options.PropertyFilter;
|
||||||
|
|
@ -281,7 +281,7 @@ public static partial class AcBinarySerializer
|
||||||
HasPropertyFilter = Options.PropertyFilter != null;
|
HasPropertyFilter = Options.PropertyFilter != null;
|
||||||
InternBit = 1 << (int)Options.UseStringInterning;
|
InternBit = 1 << (int)Options.UseStringInterning;
|
||||||
HasStringInterning = Options.UseStringInterning != StringInterningMode.None;
|
HasStringInterning = Options.UseStringInterning != StringInterningMode.None;
|
||||||
//FastWire = Options.WireMode == WireMode.Fast;
|
FastWire = Options.WireMode == WireMode.Fast;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Clear()
|
public override void Clear()
|
||||||
|
|
@ -630,17 +630,17 @@ public static partial class AcBinarySerializer
|
||||||
|
|
||||||
public void WriteStringUtf8(string value)
|
public void WriteStringUtf8(string value)
|
||||||
{
|
{
|
||||||
//if (FastWire)
|
if (FastWire)
|
||||||
//{
|
{
|
||||||
// // UTF-16: char count (fixed uint) + raw char data (zero-encoding memcopy)
|
// UTF-16: char count (VarUInt) + raw char data (zero-encoding memcopy)
|
||||||
// var charLen = value.Length;
|
var charLen = value.Length;
|
||||||
// var byteLen = charLen * 2;
|
var byteLen = charLen * 2;
|
||||||
// WriteRaw(charLen);
|
WriteVarUInt((uint)charLen);
|
||||||
// EnsureCapacity(byteLen);
|
EnsureCapacity(byteLen);
|
||||||
// MemoryMarshal.AsBytes(value.AsSpan()).CopyTo(_buffer.AsSpan(_position, byteLen));
|
MemoryMarshal.AsBytes(value.AsSpan()).CopyTo(_buffer.AsSpan(_position, byteLen));
|
||||||
// _position += byteLen;
|
_position += byteLen;
|
||||||
// return;
|
return;
|
||||||
//}
|
}
|
||||||
|
|
||||||
var charLength = value.Length;
|
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
|
// FastWire: skip FixStr optimization (UTF-8 specific), write String marker + UTF-16 data
|
||||||
//if (context.FastWire)
|
if (context.FastWire)
|
||||||
//{
|
{
|
||||||
// context.WriteByte(BinaryTypeCode.String);
|
context.WriteByte(BinaryTypeCode.String);
|
||||||
// context.WriteStringUtf8(value);
|
context.WriteStringUtf8(value);
|
||||||
// return;
|
return;
|
||||||
//}
|
}
|
||||||
|
|
||||||
// Fast path for short strings: check length first (cheap), then ASCII
|
// Fast path for short strings: check length first (cheap), then ASCII
|
||||||
// FixStr encodes type+length in single byte for strings <= 31 chars
|
// 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 UseMetadata { get; set; } = false;
|
||||||
public bool UseGeneratedCode { get; set; } = true;
|
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>
|
/// <summary>
|
||||||
/// Controls how string interning is applied during serialization.
|
/// Controls how string interning is applied during serialization.
|
||||||
/// None: No interning, all strings written inline.
|
/// None: No interning, all strings written inline.
|
||||||
|
|
@ -94,13 +101,6 @@ public sealed class AcBinarySerializerOptions : AcSerializerOptions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StringInterningMode UseStringInterning { get; set; } = StringInterningMode.Attribute;
|
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>
|
/// <summary>
|
||||||
/// When true, checks for duplicate property name hashes during serialization (UseMetadata mode).
|
/// 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.
|
/// 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)
|
// Complex types (25-31)
|
||||||
public const byte Object = 25; // Start of object (non-tracked OR first occurrence when ref tracking)
|
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 ObjectRef = 27; // Reference to previously serialized object (2+ occurrence)
|
||||||
public const byte Array = 28; // Start of array/list
|
public const byte Array = 28; // Start of array/list
|
||||||
public const byte Dictionary = 29; // Start of dictionary
|
public const byte Dictionary = 29; // Start of dictionary
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue