66 lines
3.0 KiB
C#
66 lines
3.0 KiB
C#
using AyCode.Core.Serializers;
|
|
using AyCode.Core.Tests.TestModels;
|
|
using MemoryPack;
|
|
using System.Buffers;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace AyCode.Core.Benchmarks.Workloads.Scenarios;
|
|
|
|
/// <summary>
|
|
/// Benchmarks MemoryPack via the IBufferWriter overload with a pre-allocated, reused ArrayBufferWriter.
|
|
/// Apples-to-apples counterpart to <see cref="AcBinaryBufferWriterBenchmark{T}"/> — MemoryPack's IBufferWriter
|
|
/// is the path it's designed for.
|
|
/// </summary>
|
|
public sealed class MemoryPackBufferWriterBenchmark<T> : ISerializerBenchmark where T : class
|
|
{
|
|
private readonly T _order;
|
|
private readonly MemoryPackSerializerOptions _options;
|
|
private readonly byte[] _serialized;
|
|
private readonly ArrayBufferWriter<byte> _bufferWriter;
|
|
|
|
public BenchmarkEngine Engine => BenchmarkEngine.MemoryPack;
|
|
public BenchmarkIoMode IoMode => BenchmarkIoMode.BufWrReuse;
|
|
public BenchmarkDispatchMode DispatchMode => BenchmarkDispatchMode.SGen; // MemoryPack always uses [MemoryPackable] source-generated formatters
|
|
public Type OrderType => typeof(T);
|
|
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(T order, WireMode wireMode, string optionsPreset)
|
|
{
|
|
_order = order;
|
|
OptionsPreset = optionsPreset;
|
|
_options = BenchmarkOptions.GetMemPack(wireMode);
|
|
_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<byte>(_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<byte> 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<T>(new ReadOnlySequence<byte>(_serialized), _options);
|
|
|
|
public bool VerifyRoundTrip()
|
|
{
|
|
_bufferWriter.ResetWrittenCount();
|
|
MemoryPackSerializer.Serialize(_bufferWriter, _order, _options);
|
|
var roundTripped = MemoryPackSerializer.Deserialize<T>(new ReadOnlySequence<byte>(_bufferWriter.WrittenMemory), _options);
|
|
return RoundTripValidator.DeepEqualsViaJson(_order, roundTripped);
|
|
}
|
|
}
|