Skip to content

Instantly share code, notes, and snippets.

@ismaelhamed
Created February 27, 2023 10:19
Show Gist options
  • Save ismaelhamed/ec9c38f035a352f1293e76c6d21de0e1 to your computer and use it in GitHub Desktop.
Save ismaelhamed/ec9c38f035a352f1293e76c6d21de0e1 to your computer and use it in GitHub Desktop.
ActorBenchmarks
[MemoryDiagnoser]
[SimpleJob(targetCount: 5, launchCount: 1, warmupCount: 5)]
public class ActorBenchmarks
{
[Params(100_000, 1_000_000)]
public int ActorCount { get; set; }
private ActorSystem system;
[IterationSetup]
public void Setup() => system = ActorSystem.Create("ActorBenchmark");
[IterationCleanup]
public void Cleanup() => system.Terminate().Wait();
[Benchmark(Description = "UntypedActor")]
public void SpawnUntypedActor()
{
var latch = new CountdownEvent(ActorCount);
var actor = system.ActorOf(ParentUntypedActor.Props(latch));
actor.Tell(new StartTest(ActorCount));
latch.Wait();
}
[Benchmark(Description = "ReceiveActor")]
public void SpawnReceiveActor()
{
var latch = new CountdownEvent(ActorCount);
var actor = system.ActorOf(ParentReceiveActor.Props(latch));
actor.Tell(new StartTest(ActorCount));
latch.Wait();
}
}
#region actors
internal sealed class StartTest
{
public int ActorCount { get; }
public StartTest(int actorCount) => ActorCount = actorCount;
}
internal sealed class ChildReady
{
public static readonly ChildReady Instance = new();
private ChildReady() { }
}
internal sealed class ParentReceiveActor : ReceiveActor
{
public static Props Props(CountdownEvent latch) =>
Akka.Actor.Props.Create<ParentReceiveActor>(latch);
public ParentReceiveActor(CountdownEvent latch)
{
Receive<StartTest>(start =>
{
for (var i = 0; i < start.ActorCount; i++)
Context.ActorOf(Child.Props);
});
Receive<ChildReady>(_ =>
{
if (latch.Signal()) Context.Stop(Self);
});
}
sealed class Child : ReceiveActor
{
public static readonly Props Props = Props.Create<Child>();
public Child() => ReceiveAny(_ => { });
protected override void PreStart()
{
base.PreStart();
Context.Parent.Tell(ChildReady.Instance);
}
}
}
internal sealed class ParentUntypedActor : UntypedActor
{
private readonly CountdownEvent latch;
public static Props Props(CountdownEvent latch) =>
Akka.Actor.Props.Create<ParentUntypedActor>(latch);
public ParentUntypedActor(CountdownEvent latch) => this.latch = latch;
protected override void OnReceive(object message)
{
switch (message)
{
case StartTest start:
{
for (var i = 0; i < start.ActorCount; i++)
Context.ActorOf(Child.Props);
}
break;
case ChildReady _:
if (latch.Signal()) Context.Stop(Self);
break;
}
}
sealed class Child : UntypedActor
{
public static readonly Props Props = Props.Create<Child>();
protected override void OnReceive(object message)
{
// ignore
}
protected override void PreStart()
{
base.PreStart();
Context.Parent.Tell(ChildReady.Instance);
}
}
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment