=act Optimize BehaviorBuilder and ReceiveBuilder's BuiltBehavior into array based. (#31325)
This commit is contained in:
parent
a4f8890c7b
commit
2c896fca26
3 changed files with 51 additions and 44 deletions
|
|
@ -0,0 +1,3 @@
|
|||
# #30445 performance improvements for typed javadsl message matchers
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("akka.actor.typed.javadsl.BuiltReceive.this")
|
||||
ProblemFilters.exclude[IncompatibleMethTypeProblem]("akka.actor.typed.javadsl.BuiltBehavior.this")
|
||||
|
|
@ -34,7 +34,9 @@ final class BehaviorBuilder[T] private (messageHandlers: List[Case[T, T]], signa
|
|||
/**
|
||||
* Build a Behavior from the current state of the builder
|
||||
*/
|
||||
def build(): Behavior[T] = new BuiltBehavior(messageHandlers.reverse, signalHandlers.reverse)
|
||||
def build(): Behavior[T] = {
|
||||
new BuiltBehavior[T](messageHandlers.reverse.toArray, signalHandlers.reverse.toArray)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new case to the message handling.
|
||||
|
|
@ -157,6 +159,7 @@ object BehaviorBuilder {
|
|||
private val _empty = new BehaviorBuilder[Nothing](Nil, Nil)
|
||||
|
||||
// used for both matching signals and messages so we throw away types after they are enforced by the builder API above
|
||||
|
||||
/** INTERNAL API */
|
||||
@InternalApi
|
||||
private[javadsl] final case class Case[BT, MT](
|
||||
|
|
@ -177,23 +180,25 @@ object BehaviorBuilder {
|
|||
* INTERNAL API
|
||||
*/
|
||||
@InternalApi
|
||||
private final class BuiltBehavior[T](messageHandlers: List[Case[T, T]], signalHandlers: List[Case[T, Signal]])
|
||||
private final class BuiltBehavior[T](messageHandlers: Array[Case[T, T]], signalHandlers: Array[Case[T, Signal]])
|
||||
extends ExtensibleBehavior[T] {
|
||||
|
||||
override def receive(ctx: TypedActorContext[T], msg: T): Behavior[T] = receive(msg, messageHandlers)
|
||||
override def receive(ctx: TypedActorContext[T], msg: T): Behavior[T] = receive(msg, messageHandlers, 0)
|
||||
|
||||
override def receiveSignal(ctx: TypedActorContext[T], msg: Signal): Behavior[T] =
|
||||
receive(msg, signalHandlers)
|
||||
override def receiveSignal(ctx: TypedActorContext[T], msg: Signal): Behavior[T] = receive(msg, signalHandlers, 0)
|
||||
|
||||
@tailrec
|
||||
private def receive[M](msg: M, handlers: List[Case[T, M]]): Behavior[T] =
|
||||
handlers match {
|
||||
case Case(cls, predicate, handler) :: tail =>
|
||||
private def receive[M](msg: M, handlers: Array[Case[T, M]], idx: Int): Behavior[T] = {
|
||||
if (handlers.length == 0) {
|
||||
Behaviors.unhandled[T]
|
||||
} else {
|
||||
val Case(cls, predicate, handler) = handlers(idx)
|
||||
if ((cls.isEmpty || cls.get.isAssignableFrom(msg.getClass)) && (predicate.isEmpty || predicate.get.apply(msg)))
|
||||
handler(msg)
|
||||
else receive(msg, tail)
|
||||
case Nil =>
|
||||
else if (idx == handlers.length - 1)
|
||||
Behaviors.unhandled[T]
|
||||
else
|
||||
receive(msg, handlers, idx + 1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,13 @@
|
|||
|
||||
package akka.actor.typed.javadsl
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
import akka.actor.typed.{ Behavior, Signal }
|
||||
import akka.actor.typed.MessageAdaptionFailure
|
||||
import akka.actor.typed.{ Behavior, MessageAdaptionFailure, Signal }
|
||||
import akka.annotation.InternalApi
|
||||
import akka.japi.function.{ Function => JFunction }
|
||||
import akka.japi.function.{ Predicate => JPredicate }
|
||||
import akka.japi.function.Creator
|
||||
import akka.japi.function.{ Creator, Function => JFunction, Predicate => JPredicate }
|
||||
import akka.util.OptionVal
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
/**
|
||||
* Mutable builder used when implementing [[AbstractBehavior]].
|
||||
*
|
||||
|
|
@ -33,8 +30,7 @@ final class ReceiveBuilder[T] private (
|
|||
val builtSignalHandlers =
|
||||
if (signalHandlers.isEmpty) defaultSignalHandlers[T]
|
||||
else (adapterExceptionSignalHandler[T] :: signalHandlers).reverse
|
||||
|
||||
new BuiltReceive[T](messageHandlers.reverse, builtSignalHandlers)
|
||||
new BuiltReceive[T](messageHandlers.reverse.toArray, builtSignalHandlers.toArray)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -196,24 +192,27 @@ object ReceiveBuilder {
|
|||
*/
|
||||
@InternalApi
|
||||
private final class BuiltReceive[T](
|
||||
messageHandlers: List[ReceiveBuilder.Case[T, T]],
|
||||
signalHandlers: List[ReceiveBuilder.Case[T, Signal]])
|
||||
messageHandlers: Array[ReceiveBuilder.Case[T, T]],
|
||||
signalHandlers: Array[ReceiveBuilder.Case[T, Signal]])
|
||||
extends Receive[T] {
|
||||
import ReceiveBuilder.Case
|
||||
|
||||
override def receiveMessage(msg: T): Behavior[T] = receive[T](msg, messageHandlers)
|
||||
override def receiveMessage(msg: T): Behavior[T] = receive[T](msg, messageHandlers, 0)
|
||||
|
||||
override def receiveSignal(msg: Signal): Behavior[T] = receive[Signal](msg, signalHandlers)
|
||||
override def receiveSignal(msg: Signal): Behavior[T] = receive[Signal](msg, signalHandlers, 0)
|
||||
|
||||
@tailrec
|
||||
private def receive[M](msg: M, handlers: List[Case[T, M]]): Behavior[T] =
|
||||
handlers match {
|
||||
case Case(cls, predicate, handler) :: tail =>
|
||||
private def receive[M](msg: M, handlers: Array[Case[T, M]], idx: Int): Behavior[T] = {
|
||||
if (handlers.length == 0) {
|
||||
Behaviors.unhandled[T]
|
||||
} else {
|
||||
val Case(cls, predicate, handler) = handlers(idx)
|
||||
if ((cls.isEmpty || cls.get.isAssignableFrom(msg.getClass)) && (predicate.isEmpty || predicate.get.test(msg)))
|
||||
handler(msg)
|
||||
else receive[M](msg, tail)
|
||||
case _ =>
|
||||
Behaviors.unhandled
|
||||
else if (idx == handlers.length - 1)
|
||||
Behaviors.unhandled[T]
|
||||
else
|
||||
receive(msg, handlers, idx + 1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue