|
Akka/Scala example source code file (ActorCreationPerfSpec.scala)
The ActorCreationPerfSpec.scala Akka example source code/** * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com> */ package akka.actor import scala.language.postfixOps import akka.testkit.{ PerformanceTest, ImplicitSender, AkkaSpec } import scala.concurrent.duration._ import akka.TestUtils import akka.testkit.metrics._ import org.scalatest.BeforeAndAfterAll import akka.testkit.metrics.HeapMemoryUsage import com.codahale.metrics.{ Timer, Histogram } object ActorCreationPerfSpec { final case class Create(number: Int, props: () ⇒ Props) case object Created case object IsAlive case object Alive case object WaitForChildren case object Waited class EmptyActor extends Actor { def receive = { case IsAlive ⇒ sender() ! Alive } } class EmptyArgsActor(val foo: Int, val bar: Int) extends Actor { def receive = { case IsAlive ⇒ sender() ! Alive } } class TimingDriver(hist: Histogram) extends Actor { def receive = { case IsAlive ⇒ sender() ! Alive case Create(number, propsCreator) ⇒ for (i ← 1 to number) { val start = System.nanoTime() context.actorOf(propsCreator.apply()) // yes, we are aware of this being skewed val stop = System.nanoTime() hist.update(stop - start) } sender() ! Created case WaitForChildren ⇒ context.children.foreach(_ ! IsAlive) context.become(waiting(context.children.size, sender()), discardOld = false) } def waiting(number: Int, replyTo: ActorRef): Receive = { var current = number { case Alive ⇒ current -= 1 if (current == 0) { replyTo ! Waited context.unbecome() } } } } class Driver extends Actor { def receive = { case IsAlive ⇒ sender() ! Alive case Create(number, propsCreator) ⇒ for (i ← 1 to number) { context.actorOf(propsCreator.apply()) } sender() ! Created case WaitForChildren ⇒ context.children.foreach(_ ! IsAlive) context.become(waiting(context.children.size, sender()), discardOld = false) } def waiting(number: Int, replyTo: ActorRef): Receive = { var current = number { case Alive ⇒ current -= 1 if (current == 0) { replyTo ! Waited context.unbecome() } } } } } @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) class ActorCreationPerfSpec extends AkkaSpec("akka.actor.serialize-messages = off") with ImplicitSender with MetricsKit with BeforeAndAfterAll { import ActorCreationPerfSpec._ def metricsConfig = system.settings.config val ActorCreationKey = MetricKey.fromString("actor-creation") val BlockingTimeKey = ActorCreationKey / "synchronous-part" val TotalTimeKey = ActorCreationKey / "total" val warmUp: Int = Integer.getInteger("akka.test.actor.ActorPerfSpec.warmUp", 50000) val nrOfActors: Int = Integer.getInteger("akka.test.actor.ActorPerfSpec.numberOfActors", 100000) val nrOfRepeats: Int = Integer.getInteger("akka.test.actor.ActorPerfSpec.numberOfRepeats", 3) def runWithCounterInside(metricName: String, scenarioName: String, number: Int, propsCreator: () ⇒ Props) { val hist = histogram(BlockingTimeKey / metricName) val driver = system.actorOf(Props(classOf[TimingDriver], hist), scenarioName) driver ! IsAlive expectMsg(Alive) driver ! Create(number, propsCreator) expectMsgPF(15 seconds, s"$scenarioName waiting for Created") { case Created ⇒ } driver ! WaitForChildren expectMsgPF(15 seconds, s"$scenarioName waiting for Waited") { case Waited ⇒ } driver ! PoisonPill TestUtils.verifyActorTermination(driver, 15 seconds) gc() } def runWithoutCounter(scenarioName: String, number: Int, propsCreator: () ⇒ Props): HeapMemoryUsage = { val mem = measureMemory(TotalTimeKey / scenarioName) val driver = system.actorOf(Props(classOf[Driver]), scenarioName) driver ! IsAlive expectMsg(Alive) gc() val before = mem.getHeapSnapshot driver ! Create(number, propsCreator) expectMsgPF(15 seconds, s"$scenarioName waiting for Created") { case Created ⇒ } driver ! WaitForChildren expectMsgPF(15 seconds, s"$scenarioName waiting for Waited") { case Waited ⇒ } gc() val after = mem.getHeapSnapshot driver ! PoisonPill TestUtils.verifyActorTermination(driver, 15 seconds) after diff before } def registerTests(name: String, propsCreator: () ⇒ Props) { val scenarioName = name.replaceAll("""[^\w]""", "") s"warm-up before: $name" taggedAs PerformanceTest in { if (warmUp > 0) { runWithoutCounter(s"${scenarioName}_warmup", warmUp, propsCreator) } clearMetrics() } s"measure synchronous blocked time for $name" taggedAs PerformanceTest in { // note: measuring per-actor-memory-use in this scenario is skewed as the Actor contains references to counters etc! // for measuring actor size use refer to the `runWithoutCounter` method for (i ← 1 to nrOfRepeats) { runWithCounterInside(name, s"${scenarioName}_driver_inside_$i", nrOfActors, propsCreator) } reportAndClearMetrics() } s"measure total creation time for $name" taggedAs PerformanceTest in { val avgMem = averageGauge(ActorCreationKey / name / "avg-mem-per-actor") for (i ← 1 to nrOfRepeats) { val heapUsed = timedWithKnownOps(TotalTimeKey / s"creating-$nrOfActors-actors" / name, ops = nrOfActors) { runWithoutCounter(s"${scenarioName}_driver_outside_$i", nrOfActors, propsCreator) } avgMem.add(heapUsed.used / nrOfActors) // average actor size, over nrOfRepeats // time is handled by the histogram already } reportAndClearMetrics() } } "Actor creation with actorOf" must { registerTests("Props[EmptyActor] with new Props", () ⇒ Props[EmptyActor]) val props1 = Props[EmptyActor] registerTests("Props[EmptyActor] with same Props", () ⇒ props1) registerTests("Props(new EmptyActor) new", () ⇒ { Props(new EmptyActor) }) val props2 = Props(new EmptyActor) registerTests("Props(new EmptyActor) same", () ⇒ { props2 }) registerTests("Props(classOf[EmptyArgsActor], ...) new", () ⇒ { Props(classOf[EmptyArgsActor], 4711, 1729) }) val props3 = Props(classOf[EmptyArgsActor], 4711, 1729) registerTests("Props(classOf[EmptyArgsActor], ...) same", () ⇒ { props3 }) registerTests("Props(new EmptyArgsActor(...)) new", () ⇒ { Props(new EmptyArgsActor(4711, 1729)) }) val props4 = Props(new EmptyArgsActor(4711, 1729)) registerTests("Props(new EmptyArgsActor(...)) same", () ⇒ { props4 }) } override def afterTermination() = shutdownMetrics() override def expectedTestDuration = 3 minutes } Other Akka source code examplesHere is a short list of links related to this Akka ActorCreationPerfSpec.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.