Skip to content
Permalink
Browse files

Add benchmark for receive loop with diagnostic events

Benchmarks:

|   Method |    N |     Mean |    Error |   StdDev |    Gen 0 | Gen 1 | Gen 2 |  Allocated |
|--------- |----- |---------:|---------:|---------:|---------:|------:|------:|-----------:|
|      Run | 1000 | 14.94 ms | 0.304 ms | 0.548 ms | 109.3750 |     - |     - |  892.19 KB |
| RunEvent | 1000 | 15.49 ms | 0.300 ms | 0.401 ms | 125.0000 |     - |     - | 1042.42 KB |
  • Loading branch information
bobbymcr committed Jan 26, 2020
1 parent 3951056 commit ce639100f9f8355be6197bdcffaa8b712baa8fbd
Showing with 77 additions and 8 deletions.
  1. +77 −8 DhcpServer.Perf/DhcpReceiveLoopBenchmarks.cs
@@ -5,19 +5,23 @@
namespace DhcpServer.Perf
{
using System;
using System.Diagnostics.Tracing;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using DhcpServer;
using DhcpServer.Events;

[SimpleJob(RuntimeMoniker.NetCoreApp31)]
[MemoryDiagnoser]
public class DhcpReceiveLoopBenchmarks
{
private IPEndpointV4 endpoint;
private ISocket socket;
private ISocket socketEvt;
private DhcpReceiveLoop loop;
private DhcpReceiveLoop loopEvt;
private byte[] rawReceiveBuffer;
private Memory<byte> receiveBuffer;
private Callbacks callbacks;
@@ -32,8 +36,11 @@ public void Setup()
{
this.endpoint = new IPEndpointV4(IPAddressV4.Loopback, 67);
this.socket = new DhcpSocket(this.endpoint);
DhcpInputChannelFactory channelFactory = new DhcpInputChannelFactory(this.socket);
this.loop = new DhcpReceiveLoop(channelFactory);
this.socketEvt = this.socket.WithEvents(1, SampleEventSource.Instance);
this.loop = new DhcpReceiveLoop(new DhcpInputChannelFactory(this.socket));
IDhcpInputChannelFactory factoryEvt = new DhcpInputChannelFactory(this.socketEvt)
.WithEvents(SampleEventSource.Instance, SampleEventSource.Instance);
this.loopEvt = new DhcpReceiveLoop(factoryEvt);
this.rawReceiveBuffer = new byte[500];
this.receiveBuffer = new Memory<byte>(this.rawReceiveBuffer);
this.callbacks = new Callbacks();
@@ -48,7 +55,10 @@ public void Cleanup()
}

[Benchmark]
public int Run() => this.RunAsync().Result;
public int Run() => this.RunAsync(this.loop, this.socket).Result;

[Benchmark]
public int RunEvent() => this.RunAsync(this.loopEvt, this.socketEvt).Result;

private static Memory<byte> ReadPacket(string name, byte[] raw)
{
@@ -57,11 +67,11 @@ private static Memory<byte> ReadPacket(string name, byte[] raw)
return buffer.Slice(0, length);
}

private async Task<int> RunAsync()
private async Task<int> RunAsync(DhcpReceiveLoop receive, IOutputSocket output)
{
this.callbacks.Expect(this.N);
Task receiveTask = this.loop.RunAsync(this.receiveBuffer, this.callbacks, CancellationToken.None);
await this.SendAsync();
Task receiveTask = receive.RunAsync(this.receiveBuffer, this.callbacks, CancellationToken.None);
await this.SendAsync(output);
try
{
await receiveTask;
@@ -74,14 +84,14 @@ private async Task<int> RunAsync()
throw new NotSupportedException("Should not happen");
}

private async Task SendAsync()
private async Task SendAsync(IOutputSocket output)
{
// Send slightly more than the expected number of messages
// in case some get dropped.
int n = (int)(this.N * 1.1);
for (int i = 0; i < n; ++i)
{
await this.socket.SendAsync(this.sendBuffer, this.endpoint);
await output.SendAsync(this.sendBuffer, this.endpoint);
}
}

@@ -112,5 +122,64 @@ public ValueTask OnReceiveAsync(DhcpMessageBuffer message, CancellationToken tok
return new ValueTask(Task.CompletedTask);
}
}

private sealed class SampleEventSource : IDhcpInputChannelFactoryEvents, IDhcpInputChannelEvents, ISocketEvents
{
public static readonly SampleEventSource Instance = new SampleEventSource();

private SampleEventSource()
{
}

[NonEvent]
public void CreateChannelStart(DhcpChannelId id, int bufferSize)
{
}

[NonEvent]
public void CreateChannelEnd(DhcpChannelId id, bool succeeded, Exception exception)
{
}

[NonEvent]
public void ReceiveStart(DhcpChannelId id)
{
}

[NonEvent]
public void ReceiveEnd(DhcpChannelId id, bool succeeded, DhcpError error, Exception exception)
{
}

[NonEvent]
public void DisposeStart(SocketId id)
{
}

[NonEvent]
public void DisposeEnd(SocketId id)
{
}

[NonEvent]
public void ReceiveStart(SocketId id, int bufferSize)
{
}

[NonEvent]
public void ReceiveEnd(SocketId id, int result, bool succeeded, Exception exception)
{
}

[NonEvent]
public void SendStart(SocketId id, int bufferSize, IPEndpointV4 endpoint)
{
}

[NonEvent]
public void SendEnd(SocketId id, bool succeeded, Exception exception)
{
}
}
}
}

0 comments on commit ce63910

Please sign in to comment.
You can’t perform that action at this time.