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

欢迎!请访问关于页面以获取更多关于如何使用本网站的信息。

+9
Clojure

在最近进行性能工作的时候,我发现将assoc解展开为单个调用比使用多个键要快得多(在我的特定应用中大约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 |
| 空数组映射(解展开assoc) | N/A | 51ns | 80ns | 110ns |
| | | | | |
| 20元素持久化哈希表(未解展开) | 190ns | 313ns | 551ns | 651ns |
| 20元素持久化哈希表(解展开assoc) | N/A | 250ns | 433ns | 524ns |
| | | | | |
| 记录(未解展开) | 12ns | 72ns | 105ns | 182ns |
| 记录(解展开assoc) | N/A | 21ns | 28ns | 41ns |

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

基准测试在商业服务器(8个CPU,32GB内存)上运行,使用ubuntu 12.04和Java 8的最新版本。附件包含了cpuinfounamejava -version输出。

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

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

对于这个补丁有一个悬而未决的问题:我们应该解展开这些调用多少次?update(在1.7 alpha中进行解展开)解展开为3个参数。添加更多的解展开并不困难,但这会影响assoc的可读性。

补丁: CLJ-1656-v5.patch

25 个答案

0

回复人:alexmiller

是的,内联是通过变量调用实现的。

0

回复人:tcrayford

Michael,

那个组只是将你的补丁应用到clojure master上传的版本,按照与以前相同的方式构建(你应该可以检出代码库并复制)。

0

回复人:alexmiller

补丁CLJ-1656-v5.patch似乎与旧版本的assoc(在core.clj中约在第179行)没有做什么?

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

测试套件中是否有针对assoc的N对参数的现有测试?

0

回复人:michaelblume

clojure.core中的依赖关系使得assoc必须在语法引用之前定义良好,因此我只是让它定义了两次,一次慢一些,一次快一些。我将提供一个带有arglists的补丁。对于每个新参数是否需要arglists?或者是现有的arglists就足够了?(我担心对arglists元数据的作用不够清楚)assoc的现有测试非常有限。我在我的树中有一个可生成测试,因为它似乎比为不同的参数编写案例更有趣。如果它看上去有用,我可以发布它,但它可能有点过度了。

0

回复人:michaelblume

这是我之前提到的测试补丁,比我记得的要过度了

0
by

回复人:michaelblume

那里,有代码和测试。

这也检查在varargs情况下传递给assoc!的kvs数量是偶数,这是assoc的行为。测试验证assoc和assoc!在奇数参数计数时都会抛出异常。

0
by

回复人:alexmiller

现有的参数列表是好的 - 它只是覆盖了生成的列表以用于文档目的。

你尝试过RT.assocN()相关的东西吗?

我想问的另一个问题是,人们是否真的经常这样做以至于这很重要? :)

0
by

回复人:michaelblume

更新补丁以适用于master

0
by

回复人:alexmiller

这仍然需要对不同计数的频率进行评估。根据一些非常快速的检查,传递两个kvs足够常见以至于有影响。传递三个则远不如前者常见,依此类推。但我很想从运行一些东西中得到一些关于频率的大致估计。我认为当前的展开太多(2-3个kvs可能是足够的)。

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