From 3f20948cde7d630cb9d81c424f95592990cb00b2 Mon Sep 17 00:00:00 2001 From: Loretta Date: Sun, 10 May 2026 09:47:41 +0200 Subject: [PATCH] [LOADED_DOCS: 3 files, no new loads] Use ReadOnlySequence in benchmarks for deserialization Updated all AcBinary and MemoryPack benchmark deserialization and round-trip verification methods to use ReadOnlySequence overloads instead of byte[] or ToArray(). This ensures benchmarks exercise the production-realistic deserialization path (e.g., for SignalR/Pipe consumers) and aligns buffer writer semantics across serializers. Added comments to clarify intent. No business logic was changed. --- .claude/settings.local.json | 3 ++- AyCode.Core.Serializers.Console/Program.cs | 30 ++++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index db427c3..740a5cb 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -73,7 +73,8 @@ "Bash(where PerfView.exe)", "Bash(where dotnet-trace *)", "Bash(dotnet tool *)", - "Bash(dotnet-trace convert *)" + "Bash(dotnet-trace convert *)", + "Bash(find ~/.nuget/packages/memorypack* -name \"*.cs\" 2>/dev/null | head -5; find /mnt/c/Users/Fullepi/.nuget/packages/memorypack* -name \"MemoryPackSerializer*.cs\" 2>/dev/null | head -5)" ] } } diff --git a/AyCode.Core.Serializers.Console/Program.cs b/AyCode.Core.Serializers.Console/Program.cs index b1b7907..d92b245 100644 --- a/AyCode.Core.Serializers.Console/Program.cs +++ b/AyCode.Core.Serializers.Console/Program.cs @@ -1682,14 +1682,19 @@ public static class Program AcBinarySerializer.Serialize(_order, abw, _options); } + // BufWr semantic: read from a ReadOnlySequence (the ROS overload), NOT from byte[] — + // single-segment array-backed sequence triggers the fast-path in AcBinaryDeserializer.cs:298 which + // redirects to the byte[] overload. This means the bench actually exercises the ROS-input path + // (the production-realistic surface for SignalR / Pipe consumers) rather than secretly testing + // byte[] Deser under the BufWr label. [MethodImpl(MethodImplOptions.NoInlining)] - public void Deserialize() => AcBinaryDeserializer.Deserialize(_serialized, _options); + public void Deserialize() => AcBinaryDeserializer.Deserialize(new ReadOnlySequence(_serialized), _options); public bool VerifyRoundTrip() { var abw = new ArrayBufferWriter(); AcBinarySerializer.Serialize(_order, abw, _options); - var roundTripped = AcBinaryDeserializer.Deserialize(abw.WrittenSpan.ToArray(), _options); + var roundTripped = AcBinaryDeserializer.Deserialize(new ReadOnlySequence(abw.WrittenMemory), _options); return DeepEqualsViaJson(_order, roundTripped); } } @@ -2536,14 +2541,16 @@ public static class Program MemoryPackSerializer.Serialize(abw, _order, _options); } + // BufWr semantic: read from a ReadOnlySequence overload (apples-to-apples with AcBinary's + // BufWr Deser path). MemoryPack's ROS overload also single-segment-fast-paths internally. [MethodImpl(MethodImplOptions.NoInlining)] - public void Deserialize() => MemoryPackSerializer.Deserialize(_serialized, _options); + public void Deserialize() => MemoryPackSerializer.Deserialize(new ReadOnlySequence(_serialized), _options); public bool VerifyRoundTrip() { var abw = new ArrayBufferWriter(); MemoryPackSerializer.Serialize(abw, _order, _options); - var roundTripped = MemoryPackSerializer.Deserialize(abw.WrittenSpan.ToArray(), _options); + var roundTripped = MemoryPackSerializer.Deserialize(new ReadOnlySequence(abw.WrittenMemory), _options); return DeepEqualsViaJson(_order, roundTripped); } } @@ -2597,14 +2604,19 @@ public static class Program AcBinarySerializer.Serialize(_order, _bufferWriter, _options); } + // BufWr semantic: read from a ReadOnlySequence (the ROS overload), NOT from byte[] — + // single-segment array-backed sequence triggers the fast-path in AcBinaryDeserializer.cs:298 which + // redirects to the byte[] overload. This means the bench actually exercises the ROS-input path + // (the production-realistic surface for SignalR / Pipe consumers) rather than secretly testing + // byte[] Deser under the BufWr label. [MethodImpl(MethodImplOptions.NoInlining)] - public void Deserialize() => AcBinaryDeserializer.Deserialize(_serialized, _options); + public void Deserialize() => AcBinaryDeserializer.Deserialize(new ReadOnlySequence(_serialized), _options); public bool VerifyRoundTrip() { _bufferWriter.ResetWrittenCount(); AcBinarySerializer.Serialize(_order, _bufferWriter, _options); - var roundTripped = AcBinaryDeserializer.Deserialize(_bufferWriter.WrittenSpan.ToArray(), _options); + var roundTripped = AcBinaryDeserializer.Deserialize(new ReadOnlySequence(_bufferWriter.WrittenMemory), _options); return DeepEqualsViaJson(_order, roundTripped); } } @@ -2660,14 +2672,16 @@ public static class Program MemoryPackSerializer.Serialize(_bufferWriter, _order, _options); } + // BufWr semantic: read from a ReadOnlySequence overload (apples-to-apples with AcBinary's + // BufWr Deser path). MemoryPack's ROS overload also single-segment-fast-paths internally. [MethodImpl(MethodImplOptions.NoInlining)] - public void Deserialize() => MemoryPackSerializer.Deserialize(_serialized, _options); + public void Deserialize() => MemoryPackSerializer.Deserialize(new ReadOnlySequence(_serialized), _options); public bool VerifyRoundTrip() { _bufferWriter.ResetWrittenCount(); MemoryPackSerializer.Serialize(_bufferWriter, _order, _options); - var roundTripped = MemoryPackSerializer.Deserialize(_bufferWriter.WrittenSpan.ToArray(), _options); + var roundTripped = MemoryPackSerializer.Deserialize(new ReadOnlySequence(_bufferWriter.WrittenMemory), _options); return DeepEqualsViaJson(_order, roundTripped); } }