using AyCode.Core.Tests.TestModels;
using MemoryPack;
using System.Buffers;
using System.Runtime.CompilerServices;
namespace AyCode.Core.Serializers.Console.Benchmarks;
///
/// Benchmarks MemoryPack via the IBufferWriter overload with a pre-allocated, reused ArrayBufferWriter.
/// Apples-to-apples counterpart to — MemoryPack's IBufferWriter
/// is the path it's designed for.
///
internal sealed class MemoryPackBufferWriterBenchmark : ISerializerBenchmark
{
private readonly TestOrder_All_True _order;
private readonly MemoryPackSerializerOptions _options;
private readonly byte[] _serialized;
private readonly ArrayBufferWriter _bufferWriter;
public BenchmarkEngine Engine => BenchmarkEngine.MemoryPack;
public BenchmarkIoMode IoMode => BenchmarkIoMode.BufWrReuse;
public BenchmarkDispatchMode DispatchMode => BenchmarkDispatchMode.SGen; // MemoryPack always uses [MemoryPackable] source-generated formatters
public string OptionsPreset { get; }
public int SerializedSize => _serialized.Length;
public long SetupSerializeAllocBytes { get; }
public long SetupDeserializeAllocBytes => 0;
public string? OptionsDescription => $"StringEncoding={_options.StringEncoding}";
public MemoryPackBufferWriterBenchmark(TestOrder_All_True order, string optionsPreset)
{
_order = order;
OptionsPreset = optionsPreset;
_options = BenchmarkOptions.GetMemPack();
_serialized = MemoryPackSerializer.Serialize(order, _options);
// Serialize-side setup only — see AcBinaryBufferWriterBenchmark for the full rationale.
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
var beforeSetup = GC.GetAllocatedBytesForCurrentThread();
_bufferWriter = new ArrayBufferWriter(_serialized.Length * 2);
var afterSetup = GC.GetAllocatedBytesForCurrentThread();
SetupSerializeAllocBytes = afterSetup - beforeSetup;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public void Serialize()
{
_bufferWriter.ResetWrittenCount();
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(new ReadOnlySequence(_serialized), _options);
public bool VerifyRoundTrip()
{
_bufferWriter.ResetWrittenCount();
MemoryPackSerializer.Serialize(_bufferWriter, _order, _options);
var roundTripped = MemoryPackSerializer.Deserialize(new ReadOnlySequence(_bufferWriter.WrittenMemory), _options);
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
}
}