Skip to content

Commit

Permalink
Add Benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
Enterprize1 authored and ThorstenThiel committed Sep 14, 2024
1 parent 3836e07 commit 879573d
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 5 deletions.
139 changes: 139 additions & 0 deletions src/Benchmark/Bench.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Jobs;
using Fluss;
using Fluss.Authentication;
using Fluss.Events;
using Fluss.ReadModel;
using Microsoft.Extensions.DependencyInjection;

namespace Benchmark;

[SimpleJob(baseline: true)]
[SimpleJob(RuntimeMoniker.Net90)]
[MemoryDiagnoser]
public class Bench
{
[IterationSetup]
public void Setup()
{
var sc = new ServiceCollection();
sc.AddEventSourcing();
sc.AddPoliciesFrom(typeof(Bench).Assembly);

_sp = sc.BuildServiceProvider();
}

ServiceProvider _sp = null!;

[Benchmark]
public async Task<int> PublishEventsAndReadMixedReadWrite()
{
var sum = 0;
for (var j = 0; j < 1000; j++)
{
await _sp.GetSystemUserUnitOfWorkFactory().Commit(async unitOfWork => {
for (var i = 0; i < 50; i++)
{
await unitOfWork.Publish(new TestEvent(1));
await unitOfWork.Publish(new TestEvent(2));
}
});

var unitOfWork = _sp.GetSystemUserUnitOfWork();
var readModel1 = await unitOfWork.GetReadModel<EventsEqualReadModel, int>(1);
var readModel2 = await unitOfWork.GetReadModel<EventsEqualReadModel, int>(2);
sum += readModel1.GotEvents + readModel2.GotEvents;
}

return sum;
}

[IterationSetup(Targets = [nameof(PublishEventsAndReadReadHeavySingleReadModel), nameof(PublishEventsAndReadReadHeavyMultipleReadModel)])]
public void SetupHeavyRead()
{
var sc = new ServiceCollection();
sc.AddEventSourcing();
sc.AddPoliciesFrom(typeof(Bench).Assembly);

_sp = sc.BuildServiceProvider();

_sp.GetSystemUserUnitOfWorkFactory().Commit(async unitOfWork => {
for (var i = 0; i < 10000; i++)
{
await unitOfWork.Publish(new TestEvent(i));
}
}).AsTask().Wait();
}


[Benchmark]
public async Task<int> PublishEventsAndReadReadHeavySingleReadModel()
{
var sum = 0;
for (var j = 0; j < 50000; j++)
{
var unitOfWork = _sp.GetSystemUserUnitOfWork();
var readModel1 = await unitOfWork.GetReadModel<EventsModEqualReadModel, int>(3);
sum += readModel1.GotEvents;
}

return sum;
}

[Benchmark]
public async Task<int> PublishEventsAndReadReadHeavyMultipleReadModel()
{
var sum = 0;
for (var j = 1; j < 5000; j++)
{
var unitOfWork = _sp.GetSystemUserUnitOfWork();
var readModel1 = await unitOfWork.GetReadModel<EventsModEqualReadModel, int>(j);
sum += readModel1.GotEvents;
}

return sum;
}
}

public class AllowAllPolicy : Policy {
public ValueTask<bool> AuthenticateEvent(EventEnvelope envelope, IAuthContext authContext)
{
return ValueTask.FromResult(true);
}

public ValueTask<bool> AuthenticateReadModel(IReadModel readModel, IAuthContext authContext)
{
return ValueTask.FromResult(true);
}
}

public record TestEvent(int Id) : Event;

public record EventsEqualReadModel : ReadModelWithKey<int>
{
public int GotEvents { get; private init; }

protected override EventsEqualReadModel When(EventEnvelope envelope)
{
return envelope.Event switch
{
TestEvent testEvent when testEvent.Id == Id => this with { GotEvents = GotEvents + 1 },
_ => this,
};
}
}

public record EventsModEqualReadModel : ReadModelWithKey<int>
{
public int GotEvents { get; private init; }

protected override EventsModEqualReadModel When(EventEnvelope envelope)
{
return envelope.Event switch
{
TestEvent testEvent when testEvent.Id % Id == 0 => this with { GotEvents = GotEvents + 1 },
_ => this,
};
}
}
19 changes: 19 additions & 0 deletions src/Benchmark/Benchmark.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
<PackageReference Include="Enterprize1.BenchmarkDotNet.GitCompare" Version="0.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Fluss\Fluss.csproj" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions src/Benchmark/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
using Benchmark;
using BenchmarkDotNet.Running;

BenchmarkRunner.Run<Bench>();
6 changes: 6 additions & 0 deletions src/Fluss.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fluss.Testing", "Fluss.Test
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fluss.Regen", "Fluss.Regen\Fluss.Regen.csproj", "{6E250321-6993-4B94-8600-85E15BF713FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark", "Benchmark\Benchmark.csproj", "{970AB461-4D44-4B99-AACA-7DAA569D4C34}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -42,5 +44,9 @@ Global
{6E250321-6993-4B94-8600-85E15BF713FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E250321-6993-4B94-8600-85E15BF713FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E250321-6993-4B94-8600-85E15BF713FA}.Release|Any CPU.Build.0 = Release|Any CPU
{970AB461-4D44-4B99-AACA-7DAA569D4C34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{970AB461-4D44-4B99-AACA-7DAA569D4C34}.Debug|Any CPU.Build.0 = Debug|Any CPU
{970AB461-4D44-4B99-AACA-7DAA569D4C34}.Release|Any CPU.ActiveCfg = Release|Any CPU
{970AB461-4D44-4B99-AACA-7DAA569D4C34}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
19 changes: 14 additions & 5 deletions src/Fluss/UnitOfWork/UnitOfWork.Authorization.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using Fluss.Authentication;
using Fluss.Events;
using Fluss.ReadModel;
#if !DEBUG
using Fluss.Extensions;
#endif

namespace Fluss;

Expand All @@ -21,7 +18,7 @@ private async ValueTask<bool> AuthorizeUsage(EventEnvelope envelope)

return accepted.Count > 0;
#else
return await _policies.Select(p => p.AuthenticateEvent(envelope, ac)).AnyAsync();
return await AnyAsync(_policies.Select(p => p.AuthenticateEvent(envelope, ac)));
#endif
}

Expand All @@ -37,7 +34,19 @@ private async ValueTask<bool> AuthorizeUsage(IReadModel eventListener)

return accepted.Count > 0;
#else
return await _policies.Select(p => p.AuthenticateReadModel(eventListener, ac)).AnyAsync();
return await AnyAsync(_policies.Select(p => p.AuthenticateReadModel(eventListener, ac)));
#endif
}

private static async ValueTask<bool> AnyAsync(IEnumerable<ValueTask<bool>> valueTasks)
{
foreach (var valueTask in valueTasks)
{
if (await valueTask)
{
return true;
}
}
return false;
}
}

0 comments on commit 879573d

Please sign in to comment.