diff --git a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.Read.cs b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.Read.cs index d9e10ef..14dcb6b 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.Read.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.Read.cs @@ -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(_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(_buffer.AsSpan(_position, byteLen)); + var value = new string(chars); + _position += byteLen; + return value; + } EnsureAvailable(length); diff --git a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.cs b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.cs index 049480e..4e1c736 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.cs @@ -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; } diff --git a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs index 576ebea..26ea2eb 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs @@ -242,7 +242,7 @@ public static partial class AcBinarySerializer /// Reference handling is safe because generated code inlines TryConsumeWritePlanEntry for IId types. /// 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; diff --git a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs index c34167d..dc55d1c 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.cs @@ -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 diff --git a/AyCode.Core/Serializers/Binaries/AcBinarySerializerOptions.cs b/AyCode.Core/Serializers/Binaries/AcBinarySerializerOptions.cs index 681e792..16d2b52 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinarySerializerOptions.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinarySerializerOptions.cs @@ -85,6 +85,13 @@ public sealed class AcBinarySerializerOptions : AcSerializerOptions public bool UseMetadata { get; set; } = false; public bool UseGeneratedCode { get; set; } = true; + /// + /// Wire encoding mode. + /// Compact: VarInt + UTF-8 (default, smaller output). + /// Fast: Fixed-width integers + UTF-16 (larger output, faster encode/decode). + /// + public WireMode WireMode { get; set; } = WireMode.Fast; + /// /// Controls how string interning is applied during serialization. /// None: No interning, all strings written inline. @@ -94,13 +101,6 @@ public sealed class AcBinarySerializerOptions : AcSerializerOptions /// public StringInterningMode UseStringInterning { get; set; } = StringInterningMode.Attribute; - /// - /// Wire encoding mode. - /// Compact: VarInt + UTF-8 (default, smaller output). - /// Fast: Fixed-width integers + UTF-16 (larger output, faster encode/decode). - /// - //public WireMode WireMode { get; set; } = WireMode.Compact; - /// /// 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. diff --git a/AyCode.Core/Serializers/Binaries/BinaryTypeCode.cs b/AyCode.Core/Serializers/Binaries/BinaryTypeCode.cs index 7514f5c..a83c1be 100644 --- a/AyCode.Core/Serializers/Binaries/BinaryTypeCode.cs +++ b/AyCode.Core/Serializers/Binaries/BinaryTypeCode.cs @@ -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