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

欢迎!请参考关于页面了解更多此功能的信息。

0票数
Clojure

函数组合函数 comp 在类似于 (apply comp large-seq-of-fns) 的情况下效率很低,因为它的大于 3 的参数版本会反转序列。

如果能有一个类似的 comp** (或类似)函数将是非常好的,这个函数就像 comp 一样,但是组合时是从左至右的。

7 答案

0票数

评论者为:tsdh

这是一个实现。

0票数

评论者为:tsdh

我的补丁有点奇怪。使用comp**创建的函数组合要比使用comp快得多,这是预期的,因为不需要对序列进行反转。

但是奇怪的是,使用comp创建的组合比使用comp**创建的组合评估速度快大约10-20%,尽管comp的非固定参数版本是用comp**定义的:(apply comp* (reverse (list* f1 f2 f3 fs)))

有关基准测试的详细信息,请参阅:https://groups.google.com/d/msg/clojure/MizwTxHwLE4/hGLrMfetlP8J

0票数
_评论者为:tsdh_

这里有一些基准


用户> (使用 'criterium.core)
没有
用户> (let [coll (doall (取 1000000 (重复 inc)))
       f1 (apply comp* coll)
       f2 (apply comp coll)]
       ( bench (f1 0) :verbose )
       ( println "---------------------------------------")
       ( bench (f2 0) :verbose ))
amd64 Linux 3.4.2-gentoo 2 cpu(s)
OpenJDK 64-Bit Server VM 22.0-b10
运行时参数:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n -XX:+TieredCompilation -Xmx1G -Dclojure.compile.path=/home/horn/Repos/clj/testi/target/classes -Dtesti.version=0.1.0-SNAPSHOT -Dclojure.debug=false
评估次数             : 600
             平均执行时间 : 112.324465 毫秒  95.0% CI: (112.247218 毫秒, 112.380682 毫秒)
    执行时间标准差 : 6.513809 毫秒  95.0% CI: (6.477450 毫秒, 6.553029 毫秒)
         执行时间下限信心区间 : 105.609401 毫秒  95.0% CI: (105.609401 毫秒, 105.622918 毫秒)
         执行时间上限信心区间 : 122.353763 毫秒  95.0% CI: (122.353763 毫秒, 122.405315 毫秒)
---------------------------------------
amd64 Linux 3.4.2-gentoo 2 cpu(s)
OpenJDK 64-Bit Server VM 22.0-b10
运行时参数:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n -XX:+TieredCompilation -Xmx1G -Dclojure.compile.path=/home/horn/Repos/clj/testi/target/classes -Dtesti.version=0.1.0-SNAPSHOT -Dclojure.debug=false
评估次数             : 1440
             平均执行时间 : 43.519663 毫秒  95.0% CI: (43.516732 毫秒, 43.524062 毫秒)
    执行时间标准差 : 492.299089 微秒  95.0% CI: (490.829889 微秒, 494.198137 微秒)
         执行时间下限信心区间 : 42.781398 毫秒  95.0% CI: (42.781398 毫秒, 42.781398 毫秒)
         执行时间上限信心区间 : 44.157311 毫秒  95.0% CI: (44.157311 毫秒, 44.158513 毫秒)
没有

0票数
by

评论者为:tsdh

好,我已经追踪到了性能差异。这来自于事实,即 reverse 会创建一个 clojure.lang.PersistentList,它的迭代速度比(完全实现)的 LazySeq 快得多。如果你以向量或列表的形式将 fncoll 提供到 (apply comp* fncoll),则创建的组合应用与 comp 的应用一样快。

所以对我来说,补丁是好的,也很有意义。

0票数
by

评论者:jafingerhut

2012年6月11日的补丁0001-CLJ-1010-Add-a-left-to-right-version-of-comp-comp.patch在2014年9月5日或附近对 Clojure 进行了一些提交后,不再干净地应用于最新的主分支。

我没有检查这个补丁是否容易更新。请参阅http://dev.clojure.org/display/community/Developing Patches中的“更新旧补丁”部分,了解更新补丁的建议。

0票数
by

评论者为:tsdh

这是一个更新的补丁,适用于2014年9月8日的git主分支。

0票数
by
...