using System; using System.Buffers.Binary; using BenchmarkDotNet.Attributes; using Impostor.Benchmarks.Data; using Impostor.Benchmarks.Data.Pool; using Impostor.Benchmarks.Extensions; using Impostor.Hazel; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.ObjectPool; using MessageWriter = Impostor.Benchmarks.Data.MessageWriter; namespace Impostor.Benchmarks.Tests { public class MessageReaderBenchmark { private byte[] _data; private ObjectPool _pool; [GlobalSetup] public void Setup() { var message = new MessageWriter(1024); message.StartMessage(1); message.Write((ushort)3100); message.Write((byte)100); message.Write((int) int.MaxValue); message.WritePacked(int.MaxValue); message.EndMessage(); _data = message.ToByteArray(true); MessageReader_Bytes_Pooled.Return(MessageReader_Bytes_Pooled.Get(_data)); // Services var services = new ServiceCollection(); services.AddSingleton(new DefaultObjectPoolProvider()); services.AddSingleton(serviceProvider => { var provider = serviceProvider.GetRequiredService(); var policy = new MessageReader_Bytes_Pooled_ImprovedPolicy(serviceProvider); return provider.Create(policy); }); _pool = services .BuildServiceProvider() .GetRequiredService>(); } [Benchmark] public void Span_Run_1_000_000() { for (var i = 0; i < 1_000_000; i++) { var span = _data.AsSpan(); var inner = span.ReadMessage(); _ = BinaryPrimitives.ReadUInt16LittleEndian(inner); _ = inner[2]; _ = BinaryPrimitives.ReadInt32LittleEndian(inner.Slice(3)); } } // [Benchmark] // public void Normal_Run_1_000_000() // { // for (var i = 0; i < 1_000_000; i++) // { // var reader = new MessageReader(_data); // var inner = reader.ReadMessage(); // // _ = inner.ReadUInt16(); // _ = inner.ReadByte(); // _ = inner.ReadInt32(); // // inner.ReadPackedInt32(); // } // } [Benchmark] public void Bytes_Run_1_000_000() { for (var i = 0; i < 1_000_000; i++) { var reader = new MessageReader_Bytes(_data); var inner = reader.ReadMessage(); _ = inner.ReadUInt16(); _ = inner.ReadByte(); _ = inner.ReadInt32(); // inner.ReadPackedInt32(); } } [Benchmark] public void Pooled_Bytes_Run_1_000_000() { for (var i = 0; i < 1_000_000; i++) { var reader = MessageReader_Bytes_Pooled.Get(_data); var inner = reader.ReadMessage(); _ = inner.ReadUInt16(); _ = inner.ReadByte(); _ = inner.ReadInt32(); // inner.ReadPackedInt32(); MessageReader_Bytes_Pooled.Return(inner); MessageReader_Bytes_Pooled.Return(reader); } } [Benchmark] public void Improved_Pooled_Bytes_Run_1_000_000() { using (var reader = _pool.Get()) { for (var i = 0; i < 1_000_000; i++) { reader.Update(_data); using (var inner = reader.ReadMessage()) { _ = inner.ReadUInt16(); _ = inner.ReadByte(); _ = inner.ReadInt32(); } } } } } }