using AyCode.Core.Extensions; using AyCode.Core.Tests.TestModels; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; using MessagePack; using MessagePack.Resolvers; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using JsonSerializer = System.Text.Json.JsonSerializer; namespace AyCode.Core.Benchmarks; /// /// Minimal benchmark to test if BenchmarkDotNet works without stack overflow. /// [ShortRunJob] [MemoryDiagnoser] public class MinimalBenchmark { private byte[] _data = null!; private string _json = null!; [GlobalSetup] public void Setup() { // Use very simple data - no circular references var simpleData = new { Id = 1, Name = "Test", Value = 42.5 }; _json = System.Text.Json.JsonSerializer.Serialize(simpleData); _data = Encoding.UTF8.GetBytes(_json); Console.WriteLine($"Setup complete. Data size: {_data.Length} bytes"); } [Benchmark] public int GetLength() => _data.Length; [Benchmark] public string GetJson() => _json; } /// /// Binary vs JSON benchmark with simple flat objects (no circular references). /// [ShortRunJob] [MemoryDiagnoser] public class SimpleBinaryBenchmark { private PrimitiveTestClass _testData = null!; private byte[] _binaryData = null!; private string _jsonData = null!; [GlobalSetup] public void Setup() { _testData = TestDataFactory.CreatePrimitiveTestData(); _binaryData = AcBinarySerializer.Serialize(_testData); _jsonData = AcJsonSerializer.Serialize(_testData, AcJsonSerializerOptions.WithoutReferenceHandling()); Console.WriteLine($"Binary: {_binaryData.Length} bytes, JSON: {_jsonData.Length} chars"); } [Benchmark(Description = "Binary Serialize")] public byte[] SerializeBinary() => AcBinarySerializer.Serialize(_testData); [Benchmark(Description = "JSON Serialize", Baseline = true)] public string SerializeJson() => AcJsonSerializer.Serialize(_testData, AcJsonSerializerOptions.WithoutReferenceHandling()); [Benchmark(Description = "Binary Deserialize")] public PrimitiveTestClass? DeserializeBinary() => AcBinaryDeserializer.Deserialize(_binaryData); [Benchmark(Description = "JSON Deserialize")] public PrimitiveTestClass? DeserializeJson() => AcJsonDeserializer.Deserialize(_jsonData, AcJsonSerializerOptions.WithoutReferenceHandling()); } /// /// Complex hierarchy benchmark - AcBinary vs JSON only (no MessagePack to isolate the issue). /// [ShortRunJob] [MemoryDiagnoser] [RankColumn] public class ComplexBinaryBenchmark { private TestOrder _testOrder = null!; private byte[] _acBinaryData = null!; private string _jsonData = null!; private AcBinarySerializerOptions _binaryOptions = null!; private AcJsonSerializerOptions _jsonOptions = null!; [GlobalSetup] public void Setup() { Console.WriteLine("Creating test data..."); _testOrder = TestDataFactory.CreateBenchmarkOrder( itemCount: 2, palletsPerItem: 2, measurementsPerPallet: 2, pointsPerMeasurement: 3); Console.WriteLine($"Created order with {_testOrder.Items.Count} items"); _binaryOptions = AcBinarySerializerOptions.Default; _jsonOptions = AcJsonSerializerOptions.WithoutReferenceHandling(); Console.WriteLine("Serializing AcBinary..."); _acBinaryData = AcBinarySerializer.Serialize(_testOrder, _binaryOptions); Console.WriteLine($"AcBinary size: {_acBinaryData.Length} bytes"); Console.WriteLine("Serializing JSON..."); _jsonData = AcJsonSerializer.Serialize(_testOrder, _jsonOptions); Console.WriteLine($"JSON size: {_jsonData.Length} chars"); var jsonBytes = Encoding.UTF8.GetByteCount(_jsonData); Console.WriteLine($"\n=== SIZE COMPARISON ==="); Console.WriteLine($"AcBinary: {_acBinaryData.Length,8:N0} bytes ({100.0 * _acBinaryData.Length / jsonBytes:F1}%)"); Console.WriteLine($"JSON: {jsonBytes,8:N0} bytes (100.0%)"); } [Benchmark(Description = "AcBinary Serialize")] public byte[] Serialize_AcBinary() => AcBinarySerializer.Serialize(_testOrder, _binaryOptions); [Benchmark(Description = "JSON Serialize", Baseline = true)] public string Serialize_Json() => AcJsonSerializer.Serialize(_testOrder, _jsonOptions); [Benchmark(Description = "AcBinary Deserialize")] public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize(_acBinaryData); [Benchmark(Description = "JSON Deserialize")] public TestOrder? Deserialize_Json() => AcJsonDeserializer.Deserialize(_jsonData, _jsonOptions); } /// /// Full comparison with MessagePack - separate class to isolate potential issues. /// [ShortRunJob] [MemoryDiagnoser] [RankColumn] public class MessagePackComparisonBenchmark { private TestOrder _testOrder = null!; private byte[] _acBinaryData = null!; private byte[] _msgPackData = null!; private string _jsonData = null!; private AcBinarySerializerOptions _binaryOptions = null!; private MessagePackSerializerOptions _msgPackOptions = null!; private AcJsonSerializerOptions _jsonOptions = null!; [GlobalSetup] public void Setup() { Console.WriteLine("Creating test data..."); _testOrder = TestDataFactory.CreateBenchmarkOrder( itemCount: 2, palletsPerItem: 2, measurementsPerPallet: 2, pointsPerMeasurement: 3); _binaryOptions = AcBinarySerializerOptions.Default; _msgPackOptions = ContractlessStandardResolver.Options.WithCompression(MessagePackCompression.None); _jsonOptions = AcJsonSerializerOptions.WithoutReferenceHandling(); _acBinaryData = AcBinarySerializer.Serialize(_testOrder, _binaryOptions); _jsonData = AcJsonSerializer.Serialize(_testOrder, _jsonOptions); // MessagePack serialization in try-catch to see if it fails try { Console.WriteLine("Serializing MessagePack..."); _msgPackData = MessagePackSerializer.Serialize(_testOrder, _msgPackOptions); Console.WriteLine($"MessagePack size: {_msgPackData.Length} bytes"); } catch (Exception ex) { Console.WriteLine($"MessagePack serialization failed: {ex.Message}"); _msgPackData = Array.Empty(); } var jsonBytes = Encoding.UTF8.GetByteCount(_jsonData); Console.WriteLine($"\n=== SIZE COMPARISON ==="); Console.WriteLine($"AcBinary: {_acBinaryData.Length,8:N0} bytes ({100.0 * _acBinaryData.Length / jsonBytes:F1}%)"); Console.WriteLine($"MessagePack: {_msgPackData.Length,8:N0} bytes ({100.0 * _msgPackData.Length / jsonBytes:F1}%)"); Console.WriteLine($"JSON: {jsonBytes,8:N0} bytes (100.0%)"); } [Benchmark(Description = "AcBinary Serialize")] public byte[] Serialize_AcBinary() => AcBinarySerializer.Serialize(_testOrder, _binaryOptions); [Benchmark(Description = "MessagePack Serialize", Baseline = true)] public byte[] Serialize_MsgPack() => MessagePackSerializer.Serialize(_testOrder, _msgPackOptions); [Benchmark(Description = "AcBinary Deserialize")] public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize(_acBinaryData); [Benchmark(Description = "MessagePack Deserialize")] public TestOrder? Deserialize_MsgPack() => MessagePackSerializer.Deserialize(_msgPackData, _msgPackOptions); }