AyCode.Core/AyCode.Benchmark/Workloads/Scenarios/SystemTextJsonBenchmark.cs

60 lines
2.6 KiB
C#

using AyCode.Core.Tests.TestModels;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
namespace AyCode.Core.Benchmarks.Workloads.Scenarios;
/// <summary>
/// System.Text.Json benchmark, String I/O mode. Reference comparison — uses reflection-based metadata
/// (no source-generator opt-in here). Typically NOT in the active suite (commented out in the
/// caller-side <c>CreateSerializers</c>); ranks far behind binary serializers on µs/op but provides
/// a familiar JSON baseline when needed.
/// </summary>
public sealed class SystemTextJsonBenchmark<T> : ISerializerBenchmark where T : class
{
private readonly T _order;
private readonly JsonSerializerOptions _options;
private readonly string _serialized;
private readonly byte[] _serializedUtf8;
public BenchmarkEngine Engine => BenchmarkEngine.SystemTextJson;
public BenchmarkIoMode IoMode => BenchmarkIoMode.String;
public BenchmarkDispatchMode DispatchMode => BenchmarkDispatchMode.Runtime; // System.Text.Json default uses reflection-based metadata (no source generator opt-in here)
public Type OrderType => typeof(T);
public string OptionsPreset { get; }
public int SerializedSize => _serializedUtf8.Length;
public long SetupSerializeAllocBytes => 0;
public long SetupDeserializeAllocBytes => 0;
public SystemTextJsonBenchmark(T order, string optionsPreset)
{
_order = order;
OptionsPreset = optionsPreset;
_options = new JsonSerializerOptions
{
WriteIndented = false,
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles
};
_serialized = JsonSerializer.Serialize(order, _options);
// Encoding.UTF8.GetBytes(string) does NOT prepend the BOM (the preamble is only emitted by
// GetPreamble() / stream-level writes), so this produces identical bytes to the prior
// `new UTF8Encoding(false).GetBytes(_serialized)` call. Size-reporting only.
_serializedUtf8 = Encoding.UTF8.GetBytes(_serialized);
}
[MethodImpl(MethodImplOptions.NoInlining)]
public void Serialize() => JsonSerializer.Serialize(_order, _options);
[MethodImpl(MethodImplOptions.NoInlining)]
public void Deserialize() => JsonSerializer.Deserialize<T>(_serialized, _options);
public bool VerifyRoundTrip()
{
var json = JsonSerializer.Serialize(_order, _options);
var roundTripped = JsonSerializer.Deserialize<T>(json, _options);
return RoundTripValidator.DeepEqualsViaJson(_order, roundTripped);
}
}