首页 > 解决方案 > Akka 打字比 Classic 慢

问题描述

对 Akka 经典有基本的了解后,我转向 Typed 并注意到,我的代码的类型化版本比经典版本慢得多。

任务是汇总每个工具的“报价”(包含工具名称、时间戳和价格)。

在经典代码中,我为每个乐器动态创建一个演员,并在演员系统之外保留一个 Map<Instrument, ActorRef> 以将传入的滴答声委托给。

在键入的代码中,需要一个“父级”,因此我将带有 Map 的路由逻辑移到了这个父级 Actor 中,因此我在这里最终得到了两个 Actors 类(实际的滴答声 Actor 和路由父级 Actor)。

否则,代码几乎相同,只需通过经典 api 实现一次并输入一次。

在测试这两种逻辑时(最初),我发现使用经典逻辑的版本处理 1,000,000 个滴答声的时间不到 1.5 秒,而键入的版本需要 3.5 秒多一点。

显而易见的第一个原因是将监护父级(也是路由器)移动到其自己的 PinnedDispatcher,因此它可以在自己的线程上运行,所有其他参与者使用默认线程池。这大大提高了性能,导致处理 1,000,000 个滴答声大约需要 2.1 秒。

我的问题是:有谁知道剩余的性能(0.6 秒)可能会丢失在哪里?

标签: javaakkaakka-typed

解决方案


类型化运行在经典之上(类型化Behavior<T>有效地包装在一个将消息转换为的函数中T;一旦包装,它就可以被视为基本上是经典的Receive),因此它为每个消息引入了一些开销。

我从将路由父级放在固定调度程序上的改进猜测,键入的实现通过父级发送每个滴答声,所以请注意,您会产生两次开销。根据相对于刻度数的 s 数量,键入的代码可以通过使用类似于父级Instrument的东西来更像经典代码,因此外部的代码将在更高级别:SpawnProtocolActorSystem

  • 检查本地Map<Instrument, ActorRef<Tick>>(或其他)
  • 如果有ActorRef问题的工具,请将勾选发送到该工具ActorRef
  • 否则,请向父演员索要与ActorRef<Tick>相关乐器相对应的内容;然后将结果保存ActorRef在本地Map并将刻度发送到该ActorRef

这更像是经典中的情况:消息数量(忽略内部系统消息)现在是 100 万加上Instruments 数量的 2 倍,而不是 200 万。


推荐阅读