Skip to content

Commit 45bbd3b

Browse files
added VectorClock benchmark (#4950)
* added VectorClock benchmark * fixed broken benchmark comparisons
1 parent 1800e38 commit 45bbd3b

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.Immutable;
4+
using System.Linq;
5+
using System.Text;
6+
using Akka.Benchmarks.Configurations;
7+
using Akka.Cluster;
8+
using BenchmarkDotNet.Attributes;
9+
using FluentAssertions;
10+
using static Akka.Cluster.VectorClock;
11+
12+
namespace Akka.Benchmarks.Cluster
13+
{
14+
[Config(typeof(MicroBenchmarkConfig))]
15+
public class VectorClockBenchmarks
16+
{
17+
[Params(100, 500, 1000)]
18+
public int ClockSize;
19+
20+
[Params(1000)]
21+
public int Iterations;
22+
23+
internal (VectorClock clock, ImmutableSortedSet<VectorClock.Node> nodes) CreateVectorClockOfSize(int size)
24+
{
25+
return Enumerable.Range(1, size)
26+
.Aggregate((VectorClock.Create(), ImmutableSortedSet<Node>.Empty),
27+
(tuple, i) =>
28+
{
29+
var (vc, nodes) = tuple;
30+
var node = Node.Create(i.ToString());
31+
return (vc.Increment(node), nodes.Add(node));
32+
});
33+
}
34+
35+
internal VectorClock CopyVectorClock(VectorClock vc)
36+
{
37+
var versions = vc.Versions.Aggregate(ImmutableSortedDictionary<Node, long>.Empty,
38+
(newVersions, pair) =>
39+
{
40+
return newVersions.SetItem(Node.FromHash(pair.Key.ToString()), pair.Value);
41+
});
42+
43+
return VectorClock.Create(versions);
44+
}
45+
46+
private Node _firstNode;
47+
private Node _lastNode;
48+
private Node _middleNode;
49+
private ImmutableSortedSet<Node> _nodes;
50+
private VectorClock _vcBefore;
51+
private VectorClock _vcBaseLast;
52+
private VectorClock _vcAfterLast;
53+
private VectorClock _vcConcurrentLast;
54+
private VectorClock _vcBaseMiddle;
55+
private VectorClock _vcAfterMiddle;
56+
private VectorClock _vcConcurrentMiddle;
57+
58+
[GlobalSetup]
59+
public void Setup()
60+
{
61+
var (vcBefore, nodes) = CreateVectorClockOfSize(ClockSize);
62+
_vcBefore = vcBefore;
63+
_nodes = nodes;
64+
65+
_firstNode = nodes.First();
66+
_lastNode = nodes.Last();
67+
_middleNode = nodes[ClockSize / 2];
68+
69+
_vcBaseLast = vcBefore.Increment(_lastNode);
70+
_vcAfterLast = _vcBaseLast.Increment(_firstNode);
71+
_vcConcurrentLast = _vcBaseLast.Increment(_lastNode);
72+
_vcBaseMiddle = _vcBefore.Increment(_middleNode);
73+
_vcAfterMiddle = _vcBaseMiddle.Increment(_firstNode);
74+
_vcConcurrentMiddle = _vcBaseMiddle.Increment(_middleNode);
75+
}
76+
77+
private void CheckThunkFor(VectorClock vc1, VectorClock vc2, Action<VectorClock, VectorClock> thunk, int times)
78+
{
79+
var vcc1 = CopyVectorClock(vc1);
80+
var vcc2 = CopyVectorClock(vc2);
81+
for (var i = 0; i < times; i++)
82+
{
83+
thunk(vcc1, vcc2);
84+
}
85+
}
86+
87+
private void CompareTo(VectorClock vc1, VectorClock vc2, Ordering ordering)
88+
{
89+
vc1.CompareTo(vc2).Should().Be(ordering);
90+
}
91+
92+
private void NotEqual(VectorClock vc1, VectorClock vc2)
93+
{
94+
(vc1 == vc2).Should().BeFalse();
95+
}
96+
97+
[Benchmark]
98+
public void VectorClock_comparisons_should_compare_same()
99+
{
100+
CheckThunkFor(_vcBaseLast, _vcBaseLast, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Same), Iterations);
101+
}
102+
103+
[Benchmark]
104+
public void VectorClock_comparisons_should_compare_Before_last()
105+
{
106+
CheckThunkFor(_vcBefore, _vcBaseLast, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Before), Iterations);
107+
}
108+
109+
[Benchmark]
110+
public void VectorClock_comparisons_should_compare_After_last()
111+
{
112+
CheckThunkFor(_vcAfterLast, _vcBaseLast, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.After), Iterations);
113+
}
114+
115+
[Benchmark]
116+
public void VectorClock_comparisons_should_compare_Concurrent_last()
117+
{
118+
CheckThunkFor(_vcAfterLast, _vcConcurrentLast, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Concurrent), Iterations);
119+
}
120+
121+
[Benchmark]
122+
public void VectorClock_comparisons_should_compare_Before_middle()
123+
{
124+
CheckThunkFor(_vcBefore, _vcBaseMiddle, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Before), Iterations);
125+
}
126+
127+
[Benchmark]
128+
public void VectorClock_comparisons_should_compare_After_middle()
129+
{
130+
CheckThunkFor(_vcAfterMiddle, _vcBaseMiddle, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.After), Iterations);
131+
}
132+
133+
[Benchmark]
134+
public void VectorClock_comparisons_should_compare_Concurrent_middle()
135+
{
136+
CheckThunkFor(_vcAfterMiddle, _vcConcurrentMiddle, (clock, vectorClock) => CompareTo(clock, vectorClock, Ordering.Concurrent), Iterations);
137+
}
138+
139+
[Benchmark]
140+
public void VectorClock_comparisons_should_compare_notEquals_Before_Middle()
141+
{
142+
CheckThunkFor(_vcBefore, _vcBaseMiddle, (clock, vectorClock) => NotEqual(clock, vectorClock), Iterations);
143+
}
144+
145+
[Benchmark]
146+
public void VectorClock_comparisons_should_compare_notEquals_After_Middle()
147+
{
148+
CheckThunkFor(_vcAfterMiddle, _vcBaseMiddle, (clock, vectorClock) => NotEqual(clock, vectorClock), Iterations);
149+
}
150+
151+
[Benchmark]
152+
public void VectorClock_comparisons_should_compare_notEquals_Concurrent_Middle()
153+
{
154+
CheckThunkFor(_vcAfterMiddle, _vcConcurrentMiddle, (clock, vectorClock) => NotEqual(clock, vectorClock), Iterations);
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)