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

adding ORSet benchmarks #4990

Merged
merged 7 commits into from
May 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/Akka.sln
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Akka.DependencyInjection.Te
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNetCore", "AspNetCore", "{162F5991-EA57-4221-9B70-F9B6FEC18036}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.Akka.AspNetCore", "examples\AspNetCore\Samples.Akka.AspNetCore\Samples.Akka.AspNetCore.csproj", "{D62F4AD6-318F-4ECC-B875-83FA9933A81B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.Akka.AspNetCore", "examples\AspNetCore\Samples.Akka.AspNetCore\Samples.Akka.AspNetCore.csproj", "{D62F4AD6-318F-4ECC-B875-83FA9933A81B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializationBenchmarks", "benchmark\SerializationBenchmarks\SerializationBenchmarks.csproj", "{2E4B9584-42CC-4D17-B719-9F462B16C94D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SerializationBenchmarks", "benchmark\SerializationBenchmarks\SerializationBenchmarks.csproj", "{2E4B9584-42CC-4D17-B719-9F462B16C94D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DDataStressTest", "examples\Cluster\DData\DDataStressTest\DDataStressTest.csproj", "{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -1123,6 +1125,18 @@ Global
{2E4B9584-42CC-4D17-B719-9F462B16C94D}.Release|x64.Build.0 = Release|Any CPU
{2E4B9584-42CC-4D17-B719-9F462B16C94D}.Release|x86.ActiveCfg = Release|Any CPU
{2E4B9584-42CC-4D17-B719-9F462B16C94D}.Release|x86.Build.0 = Release|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Debug|x64.ActiveCfg = Debug|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Debug|x64.Build.0 = Debug|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Debug|x86.ActiveCfg = Debug|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Debug|x86.Build.0 = Debug|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Release|Any CPU.Build.0 = Release|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Release|x64.ActiveCfg = Release|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Release|x64.Build.0 = Release|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Release|x86.ActiveCfg = Release|Any CPU
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1230,6 +1244,7 @@ Global
{162F5991-EA57-4221-9B70-F9B6FEC18036} = {D3AF8295-AEB5-4324-AA82-FCC0014AC310}
{D62F4AD6-318F-4ECC-B875-83FA9933A81B} = {162F5991-EA57-4221-9B70-F9B6FEC18036}
{2E4B9584-42CC-4D17-B719-9F462B16C94D} = {73108242-625A-4D7B-AA09-63375DBAE464}
{44B3DDD6-6103-4E8F-8AC2-0F4BA3CF6B50} = {C50E1A9E-820C-4E75-AE39-6F96A99AC4A7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {03AD8E21-7507-4E68-A4E9-F4A7E7273164}
Expand Down
129 changes: 129 additions & 0 deletions src/benchmark/Akka.Benchmarks/DData/ORSetBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Akka.Actor;
using Akka.Benchmarks.Configurations;
using Akka.Cluster;
using Akka.DistributedData;
using BenchmarkDotNet.Attributes;

namespace Akka.Benchmarks.DData
{
[Config(typeof(MicroBenchmarkConfig))]
public class ORSetBenchmarks
{
[Params(25)]
public int NumElements;

[Params(10)]
public int NumNodes;

[Params(100)]
public int Iterations;

private UniqueAddress[] _nodes;
private string[] _elements;

private readonly string _user1 = "{\"username\":\"john\",\"password\":\"coltrane\"}";
private readonly string _user2 = "{\"username\":\"sonny\",\"password\":\"rollins\"}";
private readonly string _user3 = "{\"username\":\"charlie\",\"password\":\"parker\"}";
private readonly string _user4 = "{\"username\":\"charles\",\"password\":\"mingus\"}";

// has data from all nodes
private ORSet<string> _c1 = ORSet<String>.Empty;

// has additional items from all nodes
private ORSet<string> _c2 = ORSet<String>.Empty;

// has removed items from all nodes
private ORSet<string> _c3 = ORSet<String>.Empty;

[GlobalSetup]
public void Setup()
{
var newNodes = new List<UniqueAddress>(NumNodes);
foreach(var i in Enumerable.Range(0, NumNodes)){
var address = new Address("akka.tcp", "Sys", "localhost", 2552 + i);
var uniqueAddress = new UniqueAddress(address, i);
newNodes.Add(uniqueAddress);
}
_nodes = newNodes.ToArray();

var newElements = new List<string>(NumNodes);
foreach(var i in Enumerable.Range(0, NumElements)){
newElements.Add(i.ToString());
}
_elements = newElements.ToArray();

_c1 = ORSet<String>.Empty;
foreach(var node in _nodes){
_c1 = _c1.Add(node, _elements[0]);
}

// add some data that _c2 doesn't have
_c2 = _c1;
foreach(var node in _nodes.Skip(NumNodes/2)){
_c2 = _c2.Add(node, _elements[1]);
}

_c3 = _c1;
foreach(var node in _nodes.Take(NumNodes/2)){
_c3 = _c3.Remove(node, _elements[0]);
}
}

[Benchmark]
public void Should_add_node_to_ORSet()
{
for (var i = 0; i < Iterations; i++)
{
var init = ORSet<string>.Empty;
foreach (var node in _nodes)
{
init = init.Add(node, _elements[0]);
}
}

}

[Benchmark]
public void Should_add_elements_for_Same_node()
{
for (var i = 0; i < Iterations; i++)
{
var init = ORSet<string>.Empty;
foreach (var element in _elements)
{
init = init.Add(_nodes[0], element);
}
}
}

[Benchmark]
public void Should_merge_in_new_Elements_from_other_nodes(){
for (var i = 0; i < Iterations; i++)
{
var c4 = _c1.Merge(_c2);
}

}

[Benchmark]
public void Should_merge_in_removed_Elements_from_other_nodes(){
for (var i = 0; i < Iterations; i++)
{
var c4 = _c1.Merge(_c3);
}

}

[Benchmark]
public void Should_merge_in_add_and_removed_Elements_from_other_nodes(){
for (var i = 0; i < Iterations; i++)
{
var c4 = _c1.Merge(_c2).Merge(_c3);
}
}
}
}
174 changes: 174 additions & 0 deletions src/benchmark/Akka.Benchmarks/DData/VersionVectorBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using Akka.Benchmarks.Configurations;
using Akka.Cluster;
using Akka.DistributedData;
using BenchmarkDotNet.Attributes;
using FluentAssertions;
using static Akka.DistributedData.VersionVector;

namespace Akka.Benchmarks.DData
{
[Config(typeof(MicroBenchmarkConfig))]
public class VersionVectorBenchmarks
{
[Params(100)]
public int ClockSize;

[Params(1000)]
public int Iterations;

internal (VersionVector clock, ImmutableSortedSet<UniqueAddress> nodes) CreateVectorClockOfSize(int size)
{
UniqueAddress GenerateUniqueAddress(int nodeCount){
return new UniqueAddress(new Akka.Actor.Address("akka.tcp", "ClusterSys", "localhost", nodeCount), nodeCount);
}

return Enumerable.Range(1, size)
.Aggregate((VersionVector.Empty, ImmutableSortedSet<UniqueAddress>.Empty),
(tuple, i) =>
{
var (vc, nodes) = tuple;
var node = GenerateUniqueAddress(i);
return (vc.Increment(node), nodes.Add(node));
});
}

internal VersionVector CopyVectorClock(VersionVector vc)
{
var versions = ImmutableDictionary<UniqueAddress, long>.Empty;
var enumerator = vc.VersionEnumerator;
while(enumerator.MoveNext()){
var nodePair = enumerator.Current;
versions = versions.SetItem(nodePair.Key, nodePair.Value);
}

return VersionVector.Create(versions);
}

private UniqueAddress _firstNode;
private UniqueAddress _lastNode;
private UniqueAddress _middleNode;
private ImmutableSortedSet<UniqueAddress> _nodes;
private VersionVector _vcBefore;
private VersionVector _vcBaseLast;
private VersionVector _vcAfterLast;
private VersionVector _vcConcurrentLast;
private VersionVector _vcBaseMiddle;
private VersionVector _vcAfterMiddle;
private VersionVector _vcConcurrentMiddle;

[GlobalSetup]
public void Setup()
{
var (vcBefore, nodes) = CreateVectorClockOfSize(ClockSize);
_vcBefore = vcBefore;
_nodes = nodes;

_firstNode = nodes.First();
_lastNode = nodes.Last();
_middleNode = nodes[ClockSize / 2];

_vcBaseLast = vcBefore.Increment(_lastNode);
_vcAfterLast = _vcBaseLast.Increment(_firstNode);
_vcConcurrentLast = _vcBaseLast.Increment(_lastNode);
_vcBaseMiddle = _vcBefore.Increment(_middleNode);
_vcAfterMiddle = _vcBaseMiddle.Increment(_firstNode);
_vcConcurrentMiddle = _vcBaseMiddle.Increment(_middleNode);
}

private void CheckThunkFor(VersionVector vc1, VersionVector vc2, Action<VersionVector, VersionVector> thunk, int times)
{
var vcc1 = CopyVectorClock(vc1);
var vcc2 = CopyVectorClock(vc2);
for (var i = 0; i < times; i++)
{
thunk(vcc1, vcc2);
}
}

private void CompareTo(VersionVector vc1, VersionVector vc2, Ordering ordering)
{
vc1.Compare(vc2).Should().Be(ordering);
}

private void NotEqual(VersionVector vc1, VersionVector vc2)
{
(vc1 == vc2).Should().BeFalse();
}

private void Merge(VersionVector vc1, VersionVector vc2)
{
vc1.Merge(vc2);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_same()
{
CheckThunkFor(_vcBaseLast, _vcBaseLast, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Same), Iterations);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_Before_last()
{
CheckThunkFor(_vcBefore, _vcBaseLast, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Before), Iterations);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_After_last()
{
CheckThunkFor(_vcAfterLast, _vcBaseLast, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.After), Iterations);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_Concurrent_last()
{
CheckThunkFor(_vcAfterLast, _vcConcurrentLast, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Concurrent), Iterations);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_Before_middle()
{
CheckThunkFor(_vcBefore, _vcBaseMiddle, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Before), Iterations);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_After_middle()
{
CheckThunkFor(_vcAfterMiddle, _vcBaseMiddle, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.After), Iterations);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_Concurrent_middle()
{
CheckThunkFor(_vcAfterMiddle, _vcConcurrentMiddle, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Concurrent), Iterations);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_notEquals_Before_Middle()
{
CheckThunkFor(_vcBefore, _vcBaseMiddle, (clock, vectorClock) => NotEqual(clock, vectorClock), Iterations);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_notEquals_After_Middle()
{
CheckThunkFor(_vcAfterMiddle, _vcBaseMiddle, (clock, vectorClock) => NotEqual(clock, vectorClock), Iterations);
}

[Benchmark]
public void VectorClock_comparisons_should_compare_notEquals_Concurrent_Middle()
{
CheckThunkFor(_vcAfterMiddle, _vcConcurrentMiddle, (clock, vectorClock) => NotEqual(clock, vectorClock), Iterations);
}

[Benchmark]
public void VersionVector_merge_Multi_Multi()
{
CheckThunkFor(_vcBefore, _vcAfterLast, (vector, versionVector) => Merge(vector, versionVector), Iterations);
}
}
}
24 changes: 14 additions & 10 deletions src/contrib/cluster/Akka.DistributedData.Tests/ORSetSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,20 @@ public ORSetSpec(ITestOutputHelper output)
[Fact]
public void ORSet_must_be_able_to_add_element()
{
var c1 = ORSet<string>.Empty;
var c2 = c1.Add(_node1, _user1);
var c3 = c2.Add(_node1, _user2);
var c4 = c3.Add(_node1, _user4);
var c5 = c4.Add(_node1, _user3);

Assert.Contains(_user1, c5.Elements);
Assert.Contains(_user2, c5.Elements);
Assert.Contains(_user3, c5.Elements);
Assert.Contains(_user4, c5.Elements);
for (var i = 0; i < 100; i++)
{
var c1 = ORSet<string>.Empty;
var c2 = c1.Add(_node1, _user1);
var c3 = c2.Add(_node1, _user2);
var c4 = c3.Add(_node1, _user4);
var c5 = c4.Add(_node1, _user3);

Assert.Contains(_user1, c5.Elements);
Assert.Contains(_user2, c5.Elements);
Assert.Contains(_user3, c5.Elements);
Assert.Contains(_user4, c5.Elements);
}

}

[Fact]
Expand Down
Loading