Skip to content

Commit

Permalink
Merge pull request #6162 from Aaronontheweb/backport-v1.4.44
Browse files Browse the repository at this point in the history
Backport v1.4.44 performance fixes to v1.5
  • Loading branch information
Aaronontheweb committed Oct 8, 2022
2 parents bf543ff + 43ba211 commit 04a24be
Show file tree
Hide file tree
Showing 16 changed files with 663 additions and 75 deletions.
@@ -0,0 +1,91 @@
// //-----------------------------------------------------------------------
// // <copyright file="ActorMessagingMemoryPressureBenchmark.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;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Benchmarks.Configurations;
using Akka.Routing;
using BenchmarkDotNet.Attributes;

namespace Akka.Benchmarks.Actor
{
[Config(typeof(MicroBenchmarkConfig))]
public class ActorMessagingMemoryPressureBenchmark
{
#region Classes
public sealed class StopActor
{
private StopActor(){}
public static readonly StopActor Instance = new StopActor();
}

public sealed class MyActor : ReceiveActor
{
public MyActor()
{
Receive<StopActor>(str =>
{
Context.Stop(Self);
Sender.Tell(str);
});

Receive<string>(str =>
{
Sender.Tell(str);
});
}
}
#endregion

private ActorSystem _sys;
private IActorRef _actorEntryPoint;

private const string Msg = "hit";

[Params(100_000)]
public int MsgCount { get; set; }

[Params(10, 100)]
public int ActorCount { get; set; }

[GlobalSetup]
public void Setup()
{
_sys = ActorSystem.Create("Bench", @"akka.log-dead-letters = off");
}

[GlobalCleanup]
public async Task CleanUp()
{
await _sys.Terminate();
}

[IterationCleanup]
public void PerInvokeCleanup()
{
_actorEntryPoint.GracefulStop(TimeSpan.FromSeconds(5)).Wait();
}

[IterationSetup]
public void PerInvokeSetup()
{
_actorEntryPoint = _sys.ActorOf(Props.Create<MyActor>().WithRouter(new BroadcastPool(ActorCount)));
}

[Benchmark]
public Task PushMsgs()
{
for (var i = 0; i < MsgCount; i++)
{
_actorEntryPoint.Tell(Msg);
}

return Task.CompletedTask;
}
}
}
162 changes: 162 additions & 0 deletions src/benchmark/Akka.Benchmarks/Actor/FsmBenchmarks.cs
@@ -0,0 +1,162 @@
// //-----------------------------------------------------------------------
// // <copyright file="FsmBenchmarks.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.Threading.Tasks;
using Akka.Actor;
using Akka.Benchmarks.Configurations;
using BenchmarkDotNet.Attributes;

namespace Akka.Benchmarks.Actor
{
[Config(typeof(MicroBenchmarkConfig))]
public class FsmBenchmarks
{
#region Classes

public enum States
{
Initial,
Running
}

public sealed class FsmData
{
public FsmData(string d)
{
D = d;
}

public string D { get; }
}

public class BenchmarkFsmActor : FSM<States, FsmData>
{
public BenchmarkFsmActor(string init)
{
StartWith(States.Initial, new FsmData(init));

When(States.Initial, @e =>
{
switch (e.FsmEvent)
{
case string str1 when e.StateData.D.Equals("transition"):
Sender.Tell(str1);
return GoTo(States.Running);
case string str2:
Sender.Tell(str2);
return Stay().Using(new FsmData(str2));
default:
Sender.Tell(e.FsmEvent);
return Stay();
}
});

When(States.Running, @e =>
{
switch (e.FsmEvent)
{
case string str1 when e.StateData.D.Equals("transition"):
Sender.Tell(str1);
return GoTo(States.Initial);
case string str2:
Sender.Tell(str2);
return Stay().Using(new FsmData(str2));
default:
Sender.Tell(e.FsmEvent);
return Stay();
}
});
}
}

public class UntypedActorBaseline : UntypedActor
{
private FsmData _data;

public UntypedActorBaseline(string d)
{
_data = new FsmData(d);
}

protected override void OnReceive(object message)
{
switch (message)
{
case string str1 when _data.D.Equals("transition"):
Sender.Tell(str1);
break;
case string str2:
Sender.Tell(str2);
_data = new FsmData(str2);
break;
default:
Sender.Tell(message);
break;
}
}
}

#endregion

private ActorSystem _sys;
private IActorRef _fsmActor;
private IActorRef _untypedActor;

[Params(1_000_000)]
public int MsgCount { get; set; }

[GlobalSetup]
public void Setup()
{
_sys = ActorSystem.Create("Bench", @"akka.log-dead-letters = off");
_fsmActor = _sys.ActorOf(Props.Create(() => new BenchmarkFsmActor("start")));
_untypedActor = _sys.ActorOf(Props.Create(() => new UntypedActorBaseline("start")));
}

[GlobalCleanup]
public async Task CleanUp()
{
await _sys.Terminate();
}

[Benchmark]
public async Task BenchmarkFsm()
{
for (var i = 0; i < MsgCount; i++)
{
if (i % 4 == 0)
{
_fsmActor.Tell("transition");
}
else
{
_fsmActor.Tell(i);
}
}

await _fsmActor.Ask<string>("stop");
}

[Benchmark(Baseline = true)]
public async Task BenchmarkUntyped()
{
for (var i = 0; i < MsgCount; i++)
{
if (i % 4 == 0)
{
_untypedActor.Tell("transition");
}
else
{
_untypedActor.Tell(i);
}
}

await _untypedActor.Ask<string>("stop");
}
}
}
42 changes: 42 additions & 0 deletions src/benchmark/Akka.Benchmarks/Dispatch/CallingThreadExecutor.cs
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------
// <copyright file="CallingThreadExecutor.cs" company="Akka.NET Project">
// Copyright (C) 2009-2021 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2021 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

using Akka.Configuration;
using Akka.Dispatch;

namespace Akka.Benchmarks.Dispatch
{
public class CallingThreadExecutor : ExecutorService
{
public CallingThreadExecutor(string id) : base(id)
{
}

public override void Execute(IRunnable run)
{
run.Run();
}

public override void Shutdown()
{

}
}

public class CallingThreadExecutorConfigurator : ExecutorServiceConfigurator
{
public CallingThreadExecutorConfigurator(Config config, IDispatcherPrerequisites prerequisites) : base(config, prerequisites)
{
}

public override ExecutorService Produce(string id)
{
return new CallingThreadExecutor(id);
}
}
}

0 comments on commit 04a24be

Please sign in to comment.