Skip to content

Commit

Permalink
Added a few basic benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
halgari committed Dec 13, 2023
1 parent b7e8af4 commit 77d8ca1
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 3 deletions.
9 changes: 9 additions & 0 deletions NexusMods.EventSourcing.sln
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.EventSourcing.Abs
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.EventSourcing.TestModel", "tests\NexusMods.EventSourcing.TestModel\NexusMods.EventSourcing.TestModel.csproj", "{66DCB10E-1D80-4A83-8380-B2E08BEEE7AE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{72AFE85F-8C12-436A-894E-638ED2C92A76}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.EventSourcing.Benchmarks", "benchmarks\NexusMods.EventSourcing.Benchmarks\NexusMods.EventSourcing.Benchmarks.csproj", "{96977D99-BF4B-4952-B594-6E44CCD826B9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -42,6 +46,7 @@ Global
{30CBEB4A-E0C0-4B11-A0CF-F97BFACEEF89} = {6ED01F9D-5E12-4EB2-9601-64A2ADC719DE}
{6737673E-5898-42EC-B0B2-60DE2CFFF0AF} = {0377EBE6-F147-4233-86AD-32C821B9567E}
{66DCB10E-1D80-4A83-8380-B2E08BEEE7AE} = {6ED01F9D-5E12-4EB2-9601-64A2ADC719DE}
{96977D99-BF4B-4952-B594-6E44CCD826B9} = {72AFE85F-8C12-436A-894E-638ED2C92A76}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A92DED3D-BC67-4E04-9A06-9A1B302B3070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
Expand All @@ -60,5 +65,9 @@ Global
{66DCB10E-1D80-4A83-8380-B2E08BEEE7AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66DCB10E-1D80-4A83-8380-B2E08BEEE7AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66DCB10E-1D80-4A83-8380-B2E08BEEE7AE}.Release|Any CPU.Build.0 = Release|Any CPU
{96977D99-BF4B-4952-B594-6E44CCD826B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96977D99-BF4B-4952-B594-6E44CCD826B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96977D99-BF4B-4952-B594-6E44CCD826B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96977D99-BF4B-4952-B594-6E44CCD826B9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\NexusMods.EventSourcing.Abstractions\NexusMods.EventSourcing.Abstractions.csproj" />
<ProjectReference Include="..\..\src\NexusMods.EventSourcing\NexusMods.EventSourcing.csproj" />
<ProjectReference Include="..\..\tests\NexusMods.EventSourcing.TestModel\NexusMods.EventSourcing.TestModel.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.11" />
</ItemGroup>

</Project>
18 changes: 18 additions & 0 deletions benchmarks/NexusMods.EventSourcing.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// See https://aka.ms/new-console-template for more information

using BenchmarkDotNet.Running;
using NexusMods.EventSourcing;
using NexusMods.EventSourcing.Benchmarks;
using NexusMods.EventSourcing.TestModel;


#if DEBUG
var readBenchmarks = new ReadBenchmarks();
readBenchmarks.EventStoreType = typeof(InMemoryEventStore<EventSerializer>);
readBenchmarks.EventCount = 10;
readBenchmarks.EntityCount = 10;
await readBenchmarks.Setup();
readBenchmarks.ReadEvents();
#else
BenchmarkRunner.Run<ReadBenchmarks>();
#endif
89 changes: 89 additions & 0 deletions benchmarks/NexusMods.EventSourcing.Benchmarks/ReadBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NexusMods.EventSourcing.Abstractions;
using NexusMods.EventSourcing.TestModel;
using NexusMods.EventSourcing.TestModel.Events;
using NexusMods.EventSourcing.TestModel.Model;

namespace NexusMods.EventSourcing.Benchmarks;

[MemoryDiagnoser]
public class ReadBenchmarks
{
private readonly IServiceProvider _services;
private InMemoryEventStore<EventSerializer> _eventStore = null!;
private EntityId<Loadout>[] _ids = Array.Empty<EntityId<Loadout>>();

[Params(typeof(InMemoryEventStore<EventSerializer>))]
public Type EventStoreType { get; set; } = typeof(InMemoryEventStore<EventSerializer>);

[Params(100, 10000)]
public int EventCount { get; set; }

[Params(100, 10000)]
public int EntityCount { get; set; }

public ReadBenchmarks()
{
var host = new HostBuilder()
.ConfigureServices((context, services) =>
{
services.AddEventSourcing()
.AddEvents();
})
.Build();

_services = host.Services;
}

[GlobalSetup]
public void Setup()
{
if (EventStoreType == typeof(InMemoryEventStore<EventSerializer>))
{
_eventStore = new InMemoryEventStore<EventSerializer>(_services.GetRequiredService<EventSerializer>());
}
else
{
throw new NotSupportedException($"EventStoreType '{EventStoreType}' is not supported.");
}

_ids = new EntityId<Loadout>[EntityCount];
for (var e = 0; e < EntityCount; e++)
{
var evt = new CreateLoadout(EntityId<Loadout>.NewId(), $"Loadout {e}");
_eventStore.Add(evt).GetAwaiter().GetResult();
_ids[e] = evt.Id;
}


for (var ev = 0; ev < EventCount; ev++)
{
for (var e = 0; e < EntityCount; e++)
{
_eventStore.Add(new RenameLoadout(_ids[e], $"Loadout {e} {ev}")).GetAwaiter().GetResult();
}
}

}

[Benchmark]
public void ReadEvents()
{

var ingester = new Counter();
_eventStore.EventsForEntity(_ids[_ids.Length/2].Value, ingester);
}

private class Counter : IEventIngester
{
public int Count { get; private set; }
public void Ingest(IEvent @event)
{
Count++;
}
}
}
68 changes: 68 additions & 0 deletions benchmarks/NexusMods.EventSourcing.Benchmarks/WriteBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NexusMods.EventSourcing.Abstractions;
using NexusMods.EventSourcing.TestModel;
using NexusMods.EventSourcing.TestModel.Events;
using NexusMods.EventSourcing.TestModel.Model;

namespace NexusMods.EventSourcing.Benchmarks;

[MemoryDiagnoser]
public class WriteBenchmarks
{
private readonly IServiceProvider _services;
private InMemoryEventStore<EventSerializer> _eventStore = null!;
private readonly IEvent[] _events;

[Params(typeof(InMemoryEventStore<EventSerializer>))]
public Type EventStoreType { get; set; } = typeof(InMemoryEventStore<EventSerializer>);

[Params(100, 1000, 10000)]
public int EventCount { get; set; } = 100;

public WriteBenchmarks()
{
var host = new HostBuilder()
.ConfigureServices((context, services) =>
{
services.AddEventSourcing()
.AddEvents();
})
.Build();

_events = new IEvent[]
{
new CreateLoadout(EntityId<Loadout>.NewId(), "Loadout 1"),
new SwapModEnabled(EntityId<Mod>.NewId(), true),
new DeleteMod(EntityId<Mod>.NewId(), EntityId<Loadout>.NewId())
};

_services = host.Services;
}

[IterationSetup]
public void Setup()
{
if (EventStoreType == typeof(InMemoryEventStore<EventSerializer>))
{
_eventStore = new InMemoryEventStore<EventSerializer>(_services.GetRequiredService<EventSerializer>());
}
else
{
throw new NotSupportedException($"EventStoreType '{EventStoreType}' is not supported.");
}
}

[Benchmark]
public async Task WriteEvents()
{
for (var i = 0; i < EventCount; i++)
{
var evnt = _events[i % _events.Length];
await _eventStore.Add(evnt);
}
}
}
2 changes: 1 addition & 1 deletion src/NexusMods.EventSourcing.Abstractions/IEventIngester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ public interface IEventIngester
/// </summary>
/// <param name="event"></param>
/// <returns></returns>
public ValueTask Ingest(IEvent @event);
public void Ingest(IEvent @event);
}
3 changes: 1 addition & 2 deletions tests/NexusMods.EventSourcing.Tests/Contexts/TestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,9 @@ private readonly struct Ingester(EntityId id) : IEventIngester, IEventContext
{
public readonly Dictionary<IAttribute,IAccumulator> Values = new();

public ValueTask Ingest(IEvent @event)
public void Ingest(IEvent @event)
{
@event.Apply(this);
return ValueTask.CompletedTask;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down

0 comments on commit 77d8ca1

Please sign in to comment.