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

Optimize allocations in ActorPath.Join() #4510

Merged
merged 3 commits into from
Jul 21, 2020

Conversation

petrikero
Copy link
Contributor

Optimize ActorPath.Join() to perform fewer allocations. Accessing Elements causes quite a bit of garbage to get generated.

In .NET Core or .NET Standard 2.1, the char[] buffer allocation could be avoided, but I'm sure this isn't good enough reason to require either.

The calls are mainly triggered by serialization of ActorRefs when running with Akka.Remote. We have thousands of actors running on each node and sometimes sending ActorRefs over the wire. We're mostly sending unique ActorRefs (each gets sent only once), so the caching doesn't help.

@petrikero
Copy link
Contributor Author

I tried looking at some of the failing logs, but as far as I can tell, all the errors seem unrelated. There's a lot of logs, though, so I may have easily missed something real.

@Aaronontheweb
Copy link
Member

Before:

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.388 (2004/?/20H1)
AMD Ryzen 7 1700, 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.300
[Host] : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT
DefaultJob : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT

Method Mean Error StdDev Gen 0 Gen 1 Gen 2 Allocated
ActorPath_Parse 1,926.04 ns 22.125 ns 20.695 ns 0.2689 - - 1128 B
ActorPath_Concat 57.26 ns 0.351 ns 0.329 ns 0.0421 - - 176 B
ActorPath_Equals 25.21 ns 0.270 ns 0.252 ns - - - -
ActorPath_ToString 161.39 ns 2.374 ns 2.221 ns 0.0210 - - 88 B

@Aaronontheweb
Copy link
Member

After:

// * Summary *

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.388 (2004/?/20H1)
AMD Ryzen 7 1700, 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.300
[Host] : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT
DefaultJob : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT

Method Mean Error StdDev Gen 0 Gen 1 Gen 2 Allocated
ActorPath_Parse 1,908.42 ns 7.849 ns 7.342 ns 0.2689 - - 1128 B
ActorPath_Concat 57.57 ns 0.552 ns 0.516 ns 0.0421 - - 176 B
ActorPath_Equals 25.12 ns 0.137 ns 0.122 ns - - - -
ActorPath_ToString 126.39 ns 0.770 ns 0.720 ns 0.0210 - - 88 B

@Aaronontheweb
Copy link
Member

I believe Join gets called in ToString, but let me double check - just in case we need a better benchmark for this case.

@Aaronontheweb
Copy link
Member

Yep

public string ToStringWithAddress(Address address)
{
if (Address.Host != null && Address.Port.HasValue)
return $"{Address}{Join()}";
return $"{address}{Join()}";
}

Looks like this PR improves the speed of that method by up ~22% - nicely done.

@Aaronontheweb Aaronontheweb added this to the 1.4.9 milestone Jul 21, 2020
@Aaronontheweb Aaronontheweb merged commit 7df3996 into akkadotnet:dev Jul 21, 2020
@Aaronontheweb
Copy link
Member

@petrikero yeah, those errors were unrelated - we have a large test suite and some of the tests are timing-sensitive (assert that work gets done within a bounded window of time) and those are notoriously brittle. We've been going through and hardening some, disabling others. An ongoing battle for the maintenance team here.

Thanks for this PR though - this is terrific.

This was referenced Jul 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants