diff --git a/akka-bench-jmh/src/main/scala/akka/cluster/ddata/ORSetMergeBenchmark.scala b/akka-bench-jmh/src/main/scala/akka/cluster/ddata/ORSetMergeBenchmark.scala new file mode 100644 index 0000000000..7e5872b5e3 --- /dev/null +++ b/akka-bench-jmh/src/main/scala/akka/cluster/ddata/ORSetMergeBenchmark.scala @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2015 Typesafe Inc. + */ +package akka.cluster.ddata + +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.annotations.Benchmark +import org.openjdk.jmh.annotations.BenchmarkMode +import org.openjdk.jmh.annotations.Fork +import org.openjdk.jmh.annotations.Measurement +import org.openjdk.jmh.annotations.Mode +import org.openjdk.jmh.annotations.OutputTimeUnit +import org.openjdk.jmh.annotations.{ Scope => JmhScope } +import org.openjdk.jmh.annotations.State +import org.openjdk.jmh.annotations.Warmup +import akka.actor.ActorPath +import akka.cluster.UniqueAddress +import akka.actor.Address +import org.openjdk.jmh.annotations.Param +import org.openjdk.jmh.annotations.Setup +import org.openjdk.jmh.annotations.Level + +@Fork(2) +@State(JmhScope.Benchmark) +@BenchmarkMode(Array(Mode.Throughput)) +@Warmup(iterations = 4) +@Measurement(iterations = 5) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +class ORSetMergeBenchmark { + + @Param(Array("1", "10", "20", "100")) + var set1Size = 0 + + val nodeA = UniqueAddress(Address("akka.tcp", "Sys", "aaaa", 2552), 1) + val nodeB = UniqueAddress(nodeA.address.copy(host = Some("bbbb")), 2) + val nodeC = UniqueAddress(nodeA.address.copy(host = Some("cccc")), 3) + val nodeD = UniqueAddress(nodeA.address.copy(host = Some("dddd")), 4) + val nodeE = UniqueAddress(nodeA.address.copy(host = Some("eeee")), 5) + val nodes = Vector(nodeA, nodeB, nodeC, nodeD, nodeE) + val nodesIndex = Iterator.from(0) + def nextNode(): UniqueAddress = nodes(nodesIndex.next() % nodes.size) + + var set1: ORSet[String] = _ + var addFromSameNode: ORSet[String] = _ + var addFromOtherNode: ORSet[String] = _ + var complex1: ORSet[String] = _ + var complex2: ORSet[String] = _ + var elem1: String = _ + var elem2: String = _ + + @Setup(Level.Trial) + def setup() { + set1 = (1 to set1Size).foldLeft(ORSet.empty[String])((s, n) => s.add(nextNode(), "elem" + n)) + addFromSameNode = set1.add(nodeA, "elem" + set1Size + 1).merge(set1) + addFromOtherNode = set1.add(nodeB, "elem" + set1Size + 1).merge(set1) + complex1 = set1.add(nodeB, "a").add(nodeC, "b").remove(nodeD, "elem" + set1Size).merge(set1) + complex2 = set1.add(nodeA, "a").add(nodeA, "c").add(nodeB, "d").merge(set1) + elem1 = "elem" + (set1Size + 1) + elem2 = "elem" + (set1Size + 2) + } + + @Benchmark + def mergeAddFromSameNode: ORSet[String] = { + // this is the scenario when updating and then merging with local value + // set2 produced by modify function + val set2 = set1.add(nodeA, elem1).add(nodeA, elem2) + // replicator merges with local value + set1.merge(set2) + } + + @Benchmark + def mergeAddFromOtherNode: ORSet[String] = set1.merge(addFromOtherNode) + + @Benchmark + def mergeAddFromBothNodes: ORSet[String] = addFromSameNode.merge(addFromOtherNode) + + @Benchmark + def mergeComplex: ORSet[String] = complex1.merge(complex2) + +} diff --git a/akka-bench-jmh/src/main/scala/akka/cluster/ddata/VersionVectorBenchmark.scala b/akka-bench-jmh/src/main/scala/akka/cluster/ddata/VersionVectorBenchmark.scala new file mode 100644 index 0000000000..915962014b --- /dev/null +++ b/akka-bench-jmh/src/main/scala/akka/cluster/ddata/VersionVectorBenchmark.scala @@ -0,0 +1,78 @@ +/** + * Copyright (C) 2015 Typesafe Inc. + */ +package akka.cluster.ddata + +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.annotations.Benchmark +import org.openjdk.jmh.annotations.BenchmarkMode +import org.openjdk.jmh.annotations.Fork +import org.openjdk.jmh.annotations.Measurement +import org.openjdk.jmh.annotations.Mode +import org.openjdk.jmh.annotations.OutputTimeUnit +import org.openjdk.jmh.annotations.{ Scope => JmhScope } +import org.openjdk.jmh.annotations.State +import org.openjdk.jmh.annotations.Warmup +import akka.actor.ActorPath +import akka.cluster.UniqueAddress +import akka.actor.Address +import org.openjdk.jmh.annotations.Param +import org.openjdk.jmh.annotations.Setup +import org.openjdk.jmh.annotations.Level +import scala.collection.immutable.TreeMap + +@Fork(2) +@State(JmhScope.Benchmark) +@BenchmarkMode(Array(Mode.Throughput)) +@Warmup(iterations = 4) +@Measurement(iterations = 5) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +class VersionVectorBenchmark { + + @Param(Array("1", "2", "5")) + var size = 0 + + val nodeA = UniqueAddress(Address("akka.tcp", "Sys", "aaaa", 2552), 1) + val nodeB = UniqueAddress(nodeA.address.copy(host = Some("bbbb")), 2) + val nodeC = UniqueAddress(nodeA.address.copy(host = Some("cccc")), 3) + val nodeD = UniqueAddress(nodeA.address.copy(host = Some("dddd")), 4) + val nodeE = UniqueAddress(nodeA.address.copy(host = Some("eeee")), 5) + val nodes = Vector(nodeA, nodeB, nodeC, nodeD, nodeE) + val nodesIndex = Iterator.from(0) + def nextNode(): UniqueAddress = nodes(nodesIndex.next() % nodes.size) + + var vv1: VersionVector = _ + var vv2: VersionVector = _ + var vv3: VersionVector = _ + var dot1: VersionVector = _ + + @Setup(Level.Trial) + def setup() { + vv1 = (1 to size).foldLeft(VersionVector.empty)((vv, n) => vv + nextNode()) + vv2 = vv1 + nextNode() + vv3 = vv1 + nextNode() + dot1 = VersionVector(TreeMap(nodeA -> vv1.versions(nodeA))) + } + + @Benchmark + def increment: VersionVector = (vv1 + nodeA) + + @Benchmark + def compareSame1: Boolean = (vv1 == dot1) + + @Benchmark + def compareSame2: Boolean = (vv2 == dot1) + + @Benchmark + def compareGreaterThan1: Boolean = (vv1 > dot1) + + @Benchmark + def compareGreaterThan2: Boolean = (vv2 > dot1) + + @Benchmark + def merge: VersionVector = vv1.merge(vv2) + + @Benchmark + def mergeConflicting: VersionVector = vv2.merge(vv3) + +} diff --git a/project/AkkaBuild.scala b/project/AkkaBuild.scala index fc129265b9..f8f0a60293 100644 --- a/project/AkkaBuild.scala +++ b/project/AkkaBuild.scala @@ -103,7 +103,7 @@ object AkkaBuild extends Build { lazy val benchJmh = Project( id = "akka-bench-jmh", base = file("akka-bench-jmh"), - dependencies = Seq(actor, persistence, testkit).map(_ % "compile;compile->test;provided->provided") + dependencies = Seq(actor, persistence, distributedData, testkit).map(_ % "compile;compile->test;provided->provided") ).disablePlugins(ValidatePullRequest) lazy val protobuf = Project(