=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,12 +34,14 @@ final class BehaviorBuilder[T] private (messageHandlers: List[Case[T, T]], signa
|
||||||
/**
|
/**
|
||||||
* Build a Behavior from the current state of the builder
|
* 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.
|
* Add a new case to the message handling.
|
||||||
*
|
*
|
||||||
* @param type type of message to match
|
* @param type type of message to match
|
||||||
* @param handler action to apply if the type matches
|
* @param handler action to apply if the type matches
|
||||||
* @tparam M type of message to match
|
* @tparam M type of message to match
|
||||||
* @return a new behavior builder with the specified handling appended
|
* @return a new behavior builder with the specified handling appended
|
||||||
|
|
@ -50,8 +52,8 @@ final class BehaviorBuilder[T] private (messageHandlers: List[Case[T, T]], signa
|
||||||
/**
|
/**
|
||||||
* Add a new predicated case to the message handling.
|
* Add a new predicated case to the message handling.
|
||||||
*
|
*
|
||||||
* @param type type of message to match
|
* @param type type of message to match
|
||||||
* @param test a predicate that will be evaluated on the argument if the type matches
|
* @param test a predicate that will be evaluated on the argument if the type matches
|
||||||
* @param handler action to apply if the type matches and the predicate returns true
|
* @param handler action to apply if the type matches and the predicate returns true
|
||||||
* @tparam M type of message to match
|
* @tparam M type of message to match
|
||||||
* @return a new behavior builder with the specified handling appended
|
* @return a new behavior builder with the specified handling appended
|
||||||
|
|
@ -65,7 +67,7 @@ final class BehaviorBuilder[T] private (messageHandlers: List[Case[T, T]], signa
|
||||||
* Should normally not be used, but when matching on class with generic type
|
* Should normally not be used, but when matching on class with generic type
|
||||||
* argument it can be useful, e.g. <code>List.class</code> and <code>(List<String> list) -> {...}</code>
|
* argument it can be useful, e.g. <code>List.class</code> and <code>(List<String> list) -> {...}</code>
|
||||||
*
|
*
|
||||||
* @param type type of message to match
|
* @param type type of message to match
|
||||||
* @param handler action to apply when the type matches
|
* @param handler action to apply when the type matches
|
||||||
* @return a new behavior builder with the specified handling appended
|
* @return a new behavior builder with the specified handling appended
|
||||||
*/
|
*/
|
||||||
|
|
@ -75,7 +77,7 @@ final class BehaviorBuilder[T] private (messageHandlers: List[Case[T, T]], signa
|
||||||
/**
|
/**
|
||||||
* Add a new case to the message handling matching equal messages.
|
* Add a new case to the message handling matching equal messages.
|
||||||
*
|
*
|
||||||
* @param msg the message to compare to
|
* @param msg the message to compare to
|
||||||
* @param handler action to apply when the message matches
|
* @param handler action to apply when the message matches
|
||||||
* @return a new behavior builder with the specified handling appended
|
* @return a new behavior builder with the specified handling appended
|
||||||
*/
|
*/
|
||||||
|
|
@ -98,7 +100,7 @@ final class BehaviorBuilder[T] private (messageHandlers: List[Case[T, T]], signa
|
||||||
/**
|
/**
|
||||||
* Add a new case to the signal handling.
|
* Add a new case to the signal handling.
|
||||||
*
|
*
|
||||||
* @param type type of signal to match
|
* @param type type of signal to match
|
||||||
* @param handler action to apply if the type matches
|
* @param handler action to apply if the type matches
|
||||||
* @tparam M type of signal to match
|
* @tparam M type of signal to match
|
||||||
* @return a new behavior builder with the specified handling appended
|
* @return a new behavior builder with the specified handling appended
|
||||||
|
|
@ -109,8 +111,8 @@ final class BehaviorBuilder[T] private (messageHandlers: List[Case[T, T]], signa
|
||||||
/**
|
/**
|
||||||
* Add a new predicated case to the signal handling.
|
* Add a new predicated case to the signal handling.
|
||||||
*
|
*
|
||||||
* @param type type of signals to match
|
* @param type type of signals to match
|
||||||
* @param test a predicate that will be evaluated on the argument if the type matches
|
* @param test a predicate that will be evaluated on the argument if the type matches
|
||||||
* @param handler action to apply if the type matches and the predicate returns true
|
* @param handler action to apply if the type matches and the predicate returns true
|
||||||
* @tparam M type of signal to match
|
* @tparam M type of signal to match
|
||||||
* @return a new behavior builder with the specified handling appended
|
* @return a new behavior builder with the specified handling appended
|
||||||
|
|
@ -127,7 +129,7 @@ final class BehaviorBuilder[T] private (messageHandlers: List[Case[T, T]], signa
|
||||||
/**
|
/**
|
||||||
* Add a new case to the signal handling matching equal signals.
|
* Add a new case to the signal handling matching equal signals.
|
||||||
*
|
*
|
||||||
* @param signal the signal to compare to
|
* @param signal the signal to compare to
|
||||||
* @param handler action to apply when the message matches
|
* @param handler action to apply when the message matches
|
||||||
* @return a new behavior builder with the specified handling appended
|
* @return a new behavior builder with the specified handling appended
|
||||||
*/
|
*/
|
||||||
|
|
@ -157,6 +159,7 @@ object BehaviorBuilder {
|
||||||
private val _empty = new BehaviorBuilder[Nothing](Nil, Nil)
|
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
|
// used for both matching signals and messages so we throw away types after they are enforced by the builder API above
|
||||||
|
|
||||||
/** INTERNAL API */
|
/** INTERNAL API */
|
||||||
@InternalApi
|
@InternalApi
|
||||||
private[javadsl] final case class Case[BT, MT](
|
private[javadsl] final case class Case[BT, MT](
|
||||||
|
|
@ -177,23 +180,25 @@ object BehaviorBuilder {
|
||||||
* INTERNAL API
|
* INTERNAL API
|
||||||
*/
|
*/
|
||||||
@InternalApi
|
@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] {
|
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] =
|
override def receiveSignal(ctx: TypedActorContext[T], msg: Signal): Behavior[T] = receive(msg, signalHandlers, 0)
|
||||||
receive(msg, signalHandlers)
|
|
||||||
|
|
||||||
@tailrec
|
@tailrec
|
||||||
private def receive[M](msg: M, handlers: List[Case[T, M]]): Behavior[T] =
|
private def receive[M](msg: M, handlers: Array[Case[T, M]], idx: Int): Behavior[T] = {
|
||||||
handlers match {
|
if (handlers.length == 0) {
|
||||||
case Case(cls, predicate, handler) :: tail =>
|
Behaviors.unhandled[T]
|
||||||
if ((cls.isEmpty || cls.get.isAssignableFrom(msg.getClass)) && (predicate.isEmpty || predicate.get.apply(msg)))
|
} else {
|
||||||
handler(msg)
|
val Case(cls, predicate, handler) = handlers(idx)
|
||||||
else receive(msg, tail)
|
if ((cls.isEmpty || cls.get.isAssignableFrom(msg.getClass)) && (predicate.isEmpty || predicate.get.apply(msg)))
|
||||||
case Nil =>
|
handler(msg)
|
||||||
|
else if (idx == handlers.length - 1)
|
||||||
Behaviors.unhandled[T]
|
Behaviors.unhandled[T]
|
||||||
|
else
|
||||||
|
receive(msg, handlers, idx + 1)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,13 @@
|
||||||
|
|
||||||
package akka.actor.typed.javadsl
|
package akka.actor.typed.javadsl
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import akka.actor.typed.{ Behavior, MessageAdaptionFailure, Signal }
|
||||||
|
|
||||||
import akka.actor.typed.{ Behavior, Signal }
|
|
||||||
import akka.actor.typed.MessageAdaptionFailure
|
|
||||||
import akka.annotation.InternalApi
|
import akka.annotation.InternalApi
|
||||||
import akka.japi.function.{ Function => JFunction }
|
import akka.japi.function.{ Creator, Function => JFunction, Predicate => JPredicate }
|
||||||
import akka.japi.function.{ Predicate => JPredicate }
|
|
||||||
import akka.japi.function.Creator
|
|
||||||
import akka.util.OptionVal
|
import akka.util.OptionVal
|
||||||
|
|
||||||
|
import scala.annotation.tailrec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mutable builder used when implementing [[AbstractBehavior]].
|
* Mutable builder used when implementing [[AbstractBehavior]].
|
||||||
*
|
*
|
||||||
|
|
@ -33,8 +30,7 @@ final class ReceiveBuilder[T] private (
|
||||||
val builtSignalHandlers =
|
val builtSignalHandlers =
|
||||||
if (signalHandlers.isEmpty) defaultSignalHandlers[T]
|
if (signalHandlers.isEmpty) defaultSignalHandlers[T]
|
||||||
else (adapterExceptionSignalHandler[T] :: signalHandlers).reverse
|
else (adapterExceptionSignalHandler[T] :: signalHandlers).reverse
|
||||||
|
new BuiltReceive[T](messageHandlers.reverse.toArray, builtSignalHandlers.toArray)
|
||||||
new BuiltReceive[T](messageHandlers.reverse, builtSignalHandlers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -196,24 +192,27 @@ object ReceiveBuilder {
|
||||||
*/
|
*/
|
||||||
@InternalApi
|
@InternalApi
|
||||||
private final class BuiltReceive[T](
|
private final class BuiltReceive[T](
|
||||||
messageHandlers: List[ReceiveBuilder.Case[T, T]],
|
messageHandlers: Array[ReceiveBuilder.Case[T, T]],
|
||||||
signalHandlers: List[ReceiveBuilder.Case[T, Signal]])
|
signalHandlers: Array[ReceiveBuilder.Case[T, Signal]])
|
||||||
extends Receive[T] {
|
extends Receive[T] {
|
||||||
import ReceiveBuilder.Case
|
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
|
@tailrec
|
||||||
private def receive[M](msg: M, handlers: List[Case[T, M]]): Behavior[T] =
|
private def receive[M](msg: M, handlers: Array[Case[T, M]], idx: Int): Behavior[T] = {
|
||||||
handlers match {
|
if (handlers.length == 0) {
|
||||||
case Case(cls, predicate, handler) :: tail =>
|
Behaviors.unhandled[T]
|
||||||
if ((cls.isEmpty || cls.get.isAssignableFrom(msg.getClass)) && (predicate.isEmpty || predicate.get.test(msg)))
|
} else {
|
||||||
handler(msg)
|
val Case(cls, predicate, handler) = handlers(idx)
|
||||||
else receive[M](msg, tail)
|
if ((cls.isEmpty || cls.get.isAssignableFrom(msg.getClass)) && (predicate.isEmpty || predicate.get.test(msg)))
|
||||||
case _ =>
|
handler(msg)
|
||||||
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