Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-documented slow performance of Props.Create(Expression) overload #4698

Closed
ok-ul-ch opened this issue Dec 29, 2020 · 4 comments
Closed

Non-documented slow performance of Props.Create(Expression) overload #4698

ok-ul-ch opened this issue Dec 29, 2020 · 4 comments

Comments

@ok-ul-ch
Copy link

  • Which Akka.Net version you are using: 1.4.13
  • On which platform you are using Akka.Net: .Net Core 3.1 (both Windows and Linux)
  • A list of steps to reproduce the issue: Run next benchmark code:
using Akka.Actor;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

namespace PropsCreateBenchmark
{
    class Program
    {
        static void Main(string[] args)
        {
            BenchmarkRunner.Run<PropsBenchmark>();
        }
    }

    [SimpleJob]
    public class PropsBenchmark
    {
        private static readonly string Arg = "actor arg";

        [Benchmark(Baseline = true)]
        public Props UsualProps()
        {
            var props = Props.Create<Actor>(Arg);
            return props;
        }

        [Benchmark]
        public Props ExpressionsProps()
        {
            var props = Props.Create(() => new Actor(Arg));
            return props;
        }
    }

    public class Actor : ReceiveActor
    {
        public string Arg { get; }

        public Actor(string arg)
        {
            Arg = arg;
        }
    }
}

And check results

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.592 (1909/November2018Update/19H2)
Intel Core i5-8600K CPU 3.60GHz (Coffee Lake), 1 CPU, 6 logical and 6 physical cores
.NET Core SDK=5.0.100
  [Host]     : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
  DefaultJob : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
Method Mean Error StdDev Ratio RatioSD
UsualProps 56.54 ns 1.175 ns 1.306 ns 1.00 0.00
ExpressionsProps 56,668.76 ns 1,096.394 ns 1,262.609 ns 1,002.71 31.31

As you can see from the benchmark report, creation of Props using expression is very slow and impacts performance in scenarios with a big amount of short-lived or dynamically-created actors.
Since this issue is not described in the documentation here I propose to add at least a small warning about usage of this overload.

@Aaronontheweb
Copy link
Member

Ah, so these are the performance numbers of the Props class creation, not the creation of the actor (both methods arrive at the same data structure internally.)

Ok, we can document that - this overhead is from the lamba compiler we use to extract the actor type + constructor + arguments. I think it'd be useful for users to know that.

@to11mtm
Copy link
Member

to11mtm commented Jan 6, 2021

this overhead is from the lamba compiler we use to extract the actor type + constructor + arguments.

There may be some opportunity to improve here. In a couple different projects I've had this issue and have some code that makes a best effort to avoid .Compile() and .Convert() by parsing out any constants or passed-in variables (i.e. new MyActor(configObject.ConnectionString)) and only compiling when it's more complex (i.e. function invocation) or the happy path somehow fails.

I tried out some code I had laying around for this, We can get about 10% improvement:

Before:

Method Mean Error StdDev Ratio RatioSD
UsualProps 53.34 ns 1.116 ns 1.371 ns 1.00 0.00
ExpressionsProps 35,067.76 ns 608.278 ns 568.984 ns 660.27 20.63

After:

Method Mean Error StdDev Ratio RatioSD
UsualProps 56.86 ns 1.167 ns 1.249 ns 1.00 0.00
ExpressionsProps 31,757.45 ns 326.256 ns 289.217 ns 560.25 12.69

I'll make a PR with these code changes.

@Aaronontheweb Aaronontheweb modified the milestones: 1.4.15, 1.4.16 Jan 20, 2021
@to11mtm
Copy link
Member

to11mtm commented Mar 6, 2021

@mralexes #4712 has been merged in, so next release you should see some improvement on Props.Create(Expression).

@Aaronontheweb Aaronontheweb modified the milestones: 1.4.17, 1.4.18 Mar 11, 2021
@Aaronontheweb Aaronontheweb modified the milestones: 1.4.18, 1.4.19 Mar 23, 2021
@Aaronontheweb Aaronontheweb modified the milestones: 1.4.19, 1.4.20 Apr 28, 2021
@Aaronontheweb Aaronontheweb modified the milestones: 1.4.20, 1.4.21 May 12, 2021
@Aaronontheweb Aaronontheweb modified the milestones: 1.4.21, 1.4.22 Jun 16, 2021
@Aaronontheweb Aaronontheweb modified the milestones: 1.4.22, 1.4.23 Aug 5, 2021
@Aaronontheweb
Copy link
Member

Closing this since it was address by @to11mtm and there's not a lot of wiggle room for speeding up the compression compiler, AFAIK. The Props flavors that don't use NewExpression will be faster but they are not type-safe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants