pekko/akka-bench-jmh/src/main/scala/akka/persistence/LevelDbBatchingBenchmark.scala

110 lines
3.4 KiB
Scala
Raw Normal View History

/**
* Copyright (C) 2014-2016 Lightbend Inc. <http://www.lightbend.com>
*/
package akka.persistence
import java.io.File
import java.util.concurrent.TimeUnit
import scala.concurrent.Await
import scala.concurrent.duration._
import akka.actor._
import akka.persistence.journal.AsyncWriteTarget._
import akka.persistence.journal.leveldb.{ SharedLeveldbJournal, SharedLeveldbStore }
import akka.testkit.TestProbe
import org.apache.commons.io.FileUtils
import org.openjdk.jmh.annotations._
/*
# OS: OSX 10.9.3
# CPU: Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz
# Date: Mon Jul 23 11:07:42 CEST 2014
This bench emulates what we provide with "Processor batching".
As expected, batching writes is better than writing 1 by 1.
The important thing though is that there didn't appear to be any "write latency spikes" throughout this bench.
[info] Benchmark Mode Samples Score Score error Units
[info] a.p.LevelDbBatchingBenchmark.write_1 avgt 20 0.799 0.011 ms/op
[info] a.p.LevelDbBatchingBenchmark.writeBatch_10 avgt 20 0.117 0.001 ms/op
[info] a.p.LevelDbBatchingBenchmark.writeBatch_100 avgt 20 0.050 0.000 ms/op
[info] a.p.LevelDbBatchingBenchmark.writeBatch_200 avgt 20 0.041 0.001 ms/op
*/
@Fork(1)
@Threads(10)
@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.AverageTime))
class LevelDbBatchingBenchmark {
var sys: ActorSystem = _
var probe: TestProbe = _
var store: ActorRef = _
val batch_1 = List.fill(1) { AtomicWrite(PersistentRepr("data", 12, "pa")) }
val batch_10 = List.fill(10) { AtomicWrite(PersistentRepr("data", 12, "pa")) }
val batch_100 = List.fill(100) { AtomicWrite(PersistentRepr("data", 12, "pa")) }
val batch_200 = List.fill(200) { AtomicWrite(PersistentRepr("data", 12, "pa")) }
@Setup(Level.Trial)
2016-03-05 22:34:57 -05:00
def setup():Unit = {
sys = ActorSystem("sys")
deleteStorage(sys)
SharedLeveldbJournal.setStore(store, sys)
probe = TestProbe()(sys)
store = sys.actorOf(Props[SharedLeveldbStore], "store")
}
@TearDown(Level.Trial)
2016-03-05 22:34:57 -05:00
def tearDown():Unit = {
store ! PoisonPill
Thread.sleep(500)
sys.terminate()
Await.ready(sys.whenTerminated, 10.seconds)
}
@Benchmark
@Measurement(timeUnit = TimeUnit.MICROSECONDS)
@OperationsPerInvocation(1)
2016-03-05 22:34:57 -05:00
def write_1():Unit = {
probe.send(store, WriteMessages(batch_1))
probe.expectMsgType[Any]
}
@Benchmark
@Measurement(timeUnit = TimeUnit.MICROSECONDS)
@OperationsPerInvocation(10)
2016-03-05 22:34:57 -05:00
def writeBatch_10():Unit = {
probe.send(store, WriteMessages(batch_10))
probe.expectMsgType[Any]
}
@Benchmark
@Measurement(timeUnit = TimeUnit.MICROSECONDS)
@OperationsPerInvocation(100)
2016-03-05 22:34:57 -05:00
def writeBatch_100():Unit = {
probe.send(store, WriteMessages(batch_100))
probe.expectMsgType[Any]
}
@Benchmark
@Measurement(timeUnit = TimeUnit.MICROSECONDS)
@OperationsPerInvocation(200)
2016-03-05 22:34:57 -05:00
def writeBatch_200():Unit = {
probe.send(store, WriteMessages(batch_200))
probe.expectMsgType[Any]
}
// TOOLS
private def deleteStorage(sys: ActorSystem) {
val storageLocations = List(
"akka.persistence.journal.leveldb.dir",
"akka.persistence.journal.leveldb-shared.store.dir",
"akka.persistence.snapshot-store.local.dir").map(s new File(sys.settings.config.getString(s)))
storageLocations.foreach(FileUtils.deleteDirectory)
}
}