Skip to content

Commit

Permalink
Added Dispatcher Benchmarks (#6140)
Browse files Browse the repository at this point in the history
* added parameterized Dispatcher benchmarks

* fixed naming - also, pull all config from Akka defaults
  • Loading branch information
Aaronontheweb committed Oct 8, 2022
1 parent 352d9a1 commit dbdc4e1
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 0 deletions.
121 changes: 121 additions & 0 deletions src/benchmark/Akka.Benchmarks/Dispatch/DispatcherBenchmarks.cs
@@ -0,0 +1,121 @@
// //-----------------------------------------------------------------------
// // <copyright file="DispatcherBenchmarks.cs" company="Akka.NET Project">
// // Copyright (C) 2009-2022 Lightbend Inc. <http://www.lightbend.com>
// // Copyright (C) 2013-2022 .NET Foundation <https://github.com/akkadotnet/akka.net>
// // </copyright>
// //-----------------------------------------------------------------------

using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Benchmarks.Configurations;
using Akka.Configuration;
using Akka.Dispatch;
using BenchmarkDotNet.Attributes;
using IRunnable = Akka.Dispatch.IRunnable;

namespace Akka.Benchmarks.Dispatch
{
/// <summary>
/// Used to test the performance of various dispatchers
/// </summary>
[Config(typeof(MicroBenchmarkConfig))]
public class DispatcherBenchmarks
{
private ActorSystem _sys;
private DefaultDispatcherPrerequisites _prereqs;

private MessageDispatcher _dispatcher;

[Params(1_000_000)] // higher values will cause the CallingThreadDispatcher to stack overflow
public int TaskCount { get; set; }

[ParamsSource(nameof(AllConfigurators))]
public DispatcherConfig Configurator { get; set; }

public class DispatcherConfig
{
public DispatcherConfig(Config config, string name)
{
Config = config;
Name = name;
}

public Config Config { get; }

public string Name { get; }

public override string ToString()
{
return Name;
}
}

private static readonly Config DefaultConfig = Akka.Remote.Configuration.RemoteConfigFactory.Default()
.WithFallback(Akka.Configuration.ConfigurationFactory.Default());

public IEnumerable<DispatcherConfig> AllConfigurators()
{
yield return new DispatcherConfig(DefaultConfig.GetConfig("akka.actor.default-dispatcher"), "DefaultThreadPool");
yield return new DispatcherConfig(DefaultConfig.GetConfig("akka.actor.internal-dispatcher"), "ForkJoin(sys)");
yield return new DispatcherConfig(DefaultConfig.GetConfig("akka.remote.default-remote-dispatcher"), "ForkJoin(remote)");
yield return new DispatcherConfig(@" executor = channel-executor
throughput=30", "ChannelD");
yield return new DispatcherConfig(@" executor = task-executor
throughput=30", "TaskD");
}

private TaskCompletionSource<int> _tcs;

public sealed class RunnableTarget : IRunnable
{
private readonly TaskCompletionSource<int> _tcs;
private readonly int _target;
private int _counter = 0;

public RunnableTarget(TaskCompletionSource<int> tcs, int target)
{
_tcs = tcs;
_target = target;
}

public void Run()
{
if (Interlocked.Increment(ref _counter) >= _target)
{
_tcs.TrySetResult(_counter);
}
}
}

private RunnableTarget _runnable;


[GlobalSetup]
public void Setup()
{
_sys = ActorSystem.Create("Bench");
_prereqs = new DefaultDispatcherPrerequisites(_sys.EventStream, _sys.Scheduler, _sys.Settings,
_sys.Mailboxes);
var configurator = new DispatcherConfigurator(Configurator.Config, _prereqs);
_dispatcher = configurator.Dispatcher();
_tcs = new TaskCompletionSource<int>();
_runnable = new RunnableTarget(_tcs, TaskCount);
}

[GlobalCleanup]
public void CleanUp()
{
_sys.Terminate().Wait();
}

[Benchmark]
public async Task RunDispatcher()
{
for (var i = 0; i < TaskCount; i++)
_dispatcher.Schedule(_runnable);
await _tcs.Task;
}
}
}
Expand Up @@ -69,6 +69,12 @@ public void Setup()
_msg = new Envelope("hit", ActorRefs.NoSender);
}

[GlobalCleanup]
public void CleanUp()
{
_system.Terminate().Wait();
}

[IterationSetup]
public void IterationSetup()
{
Expand Down

0 comments on commit dbdc4e1

Please sign in to comment.