2024年Clojure调查!中分享您的想法。

欢迎!请参阅关于页面了解如何使用本服务。

+9
Clojure

最近在进行性能工作时,我发现将关联展开为单个关联调用比使用多个键要快得多(在我的特定应用中大约快了10%)。Zachary Tellman随后指出,clojure.core根本不会对关联进行展开,即使是相对较低数量的键。

我们已将其他性能关键函数解耦,例如通过apply调用,例如update https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L5914,但assoc(我认为它在许多应用和库中的关键路径上),可能会从中受益。

我尚未为这个功能开发补丁,但我做了一些独立基准测试的工作

https://github.com/yeller/unrolling-assoc-benchmarks

基准测试结果

代码: https://github.com/yeller/unrolling-assoc-benchmarks/blob/master/src/bench_assoc_unrolling.clj

| |1 |2 |3 |4 |
| :-- | :-- | :-- | :-- | :-- |
| 空数组映射(未展开) | 23ns | 93ns | 156ns | 224ns |
| 空数组映射(展开关联) | N/A | 51ns | 80ns | 110ns |
| | | | | |
| 20个元素的持久性哈希映射(未展开) | 190ns | 313ns | 551ns | 651ns |
| 20个元素的持久性哈希映射(展开关联) | N/A | 250ns | 433ns | 524ns |
| | | | | |
| 记录(未展开) | 12ns | 72ns | 105ns | 182ns |
| 记录(展开关联) | N/A | 21ns | 28ns | 41ns |

每个测量都是在独立的JVM中进行的,以避免JIT路径依赖。

基准测试在一台普通服务器上运行(8个CPU,32G内存),使用Ubuntu 12.04 和最新的Java 8版本。附上cpuinfounamejava -version的输出。

启用了相对标准的JVM生产标志,并小心禁用了leiningen的启动时间优化(这禁用了许多JIT优化)。

可以通过克隆仓库并运行script/bench来运行基准测试。

关于此补丁有一个悬而未决的问题:我们应该将这此调用展开多远?update(在第1.7 alpha中展开)展开为3个参数。增加更多解耦并不困难,但这会影响关联的可读性。

补丁:CLJ-1656-v5.patch

25 答案

0

评论者:alexmiller

是的,内联通过var调用来实现。

0

评论者:tcrayford

Michael,

那个组仅仅是应用了您的补丁的上传版本 clojure master,按照以前完全相同的方式构建的,您应该可以检出仓库并复刻。

0

评论者:alexmiller

补丁 CLJ-1656-v5.patch 在老版本的 assoc (在 core.clj 约179行) 似乎没有做任何事情?

新的版本需要 arglists 和其他类似的东西。我不确定那里的宏/私有变量,您尝试过利用 RT.assocN() 与一个向量一起用吗?

测试套件中存在针对具有 N 对的 assoc 的现有测试吗?

0

评论者:michaelblume

clojure.core中的依赖关系使得 assoc 必须在语法引用之前被正确定义,所以我就让它被定义了两次,一次慢,一次快。我将提供一个带有 arglists 的补丁。是否需要为每个新 arities 提供一个 arglist,或者是现有的 arglists 足够?(我担心我对 arglists 元数据的了解不够充分) 对于 assoc 的现有测试非常不足。我在我的代码树中有一个生成性测试,因为它似乎比为所有不同的 arities 写用例更有趣。如果有用,我可以发给你,但可能有些过度。

0

评论者:michaelblume

这就是我提到的测试补丁,比我记忆中还要多

0

评论者:michaelblume

那里,代码和测试。

这也检查在 varargs 情况下,assoc! 接收到偶数个 kvs,这是 assoc 的行为。测试验证了assoc和 assoc! 在奇数参数计数时都会抛出异常。

0

评论者:alexmiller

现有的参数列表是好的——它只是为了文档目的覆盖了生成的那个。

你尝试过任何 RT.assocN() 的东西吗?

我想另一个问题是,人们是否真正做了很多这样的事情,以至于它很重要? :)

0

评论者:michaelblume

更新补丁以应用于 master

0

评论者:alexmiller

这还需要对不同计数的频率进行评估。根据一些非常快速的检查,传递两个 kv 非常常见,足以引起注意。传递三个就很少见,以此类推。但我想看到一些从运行一些内容中得到的关于频率的大致想法。我认为当前的展开太多了(2-3 kv 可能足够)。

0
参考:https://clojure.atlassian.net/browse/CLJ-1656(由 tcrayford 报告)
...