Clojure 的代理与 Scala 的演员相比如何?
Posted
技术标签:
【中文标题】Clojure 的代理与 Scala 的演员相比如何?【英文标题】:How Clojure's agents compare to Scala's actors? 【发布时间】:2011-03-16 14:46:57 【问题描述】:我在 Scala (source here) (Scala 2.8 RC7) 和 Clojure (source here) (Clojure 1.1) 中编写了 Ring network topology 的模拟,用于比较 Actor 和 Agent。
当我将网络中的节点数量从 100 增加到 1000000 时,Scala 版本显示几乎恒定的消息交换率,而 Clojure 版本显示消息交换率随着节点数量的增加而降低。同样在单次运行期间,Clojure 版本中的消息速率会随着时间的推移而降低。
所以我很好奇 Scala 的 Actors 与 Clojure 的 Agents 相比如何? Agents 的并发性是否天生不如 Actors,或者代码编写效率低(自动装箱?)?
PS:我注意到 Scala 版本中的内存使用量随着节点数量的增加而增加很多(> 500 MB 对于 100 万个节点),而 Clojure 使用的内存要少得多(~ 100 MB 对于 100 万个节点)节点)。
编辑:
两个版本都在同一个 JVM 上运行,所有 JVM 参数以及 Actor 和 Agent 配置参数都设置为默认值。在我的机器上,Scala 版本始终为 100 到 100 万个节点提供大约 5000 条消息/秒的消息速率,而 Clojure 版本从 100 个节点的 60000 条消息/秒开始,对于 100 万个节点降低到 200 条消息/秒。
编辑 2
原来我的 Clojure 版本的编写效率很低。我将nodes
集合的类型从list
更改为vector
,现在它显示出一致的行为:100 个节点为 100000 条消息/秒,100000 个节点为 80000 条消息/秒。所以 Clojure 代理似乎比 Scala Actors 更快。我也更新了链接的来源。
【问题讨论】:
有一种方法可以使 Scala 演员“无线程”。我对 Clojure 了解不多,但如果您发布(相关部分)源代码会很好。 他链接到两个版本的源代码。 在您的Edit 2
中,您可能是指inefficiently
?
我不知道 Scala,所以我在这里唯一能说的是有两个演员一个(女巫不能很好地扩展)是每个线程一个演员,另一个是基于事件的所以也许那是一种改进你的scala代码的方法?关于代理,我唯一能说的是来自线程池的使用威胁。我想在这里得到一位专家的答复。或许可以在 Clojure 和 Scala 组上提问。
查看 Viktor 提到的 Akka 中的 benchmark 实现,有一个 Akka 实现和一个标准 Scala actor 实现
【参考方案1】:
[免责声明:我是 Akka 团队的一员]
Clojure 代理与 Scala 演员是不同的野兽,最值得注意的是,如果您考虑谁控制行为。在 Agents 中,行为在外部定义并被推送到 Agent,而在 Actors 中,行为在 Actor 内部定义。
在对您的代码一无所知的情况下,我真的不能说太多,您是使用相同的 JVM 参数、为Actors 使用相同的、合理的设置与为Agents 的合理设置进行预热,还是它们是单独调整的?
附带说明: Akka 有一个环形长凳的实现位于此处:http://github.com/jboner/akka-bench/tree/master/ring/
将结果与您在机器上的 Clojure 测试进行比较会很有趣。
【讨论】:
这已经***年了,现在 :) 看到更新会非常有趣,因为 clojure 大约是 1.5.1 版本,而 scala 大约是 2.10.1 @Reb.Cabin 出于兴趣,我更新了代码以在最新的 Scala (2.11.2)、Akka (2.3.5) 和 Clojure (1.6.0) 版本上运行。 Clojure 得到了类似的结果(1K 到 100K 节点约为 80K msg/sec),但 Scala 的性能要好得多(10M 节点 +1M msg/sec)。这可能是意料之中的,因为 Akka 团队会积极优化消息吞吐量,而 Clojure 解决方案更通用。以上是关于Clojure 的代理与 Scala 的演员相比如何?的主要内容,如果未能解决你的问题,请参考以下文章
预售┃Scala与Clojure函数式编程模式:Java虚拟机高效编程