Clojure还原程序未按预期调用联合函数
我正在使用clojure reducers库进行实验,对于何时将合并函数作为reducers/fold函数的一部分进行调用,我有点困惑。为了查看何时调用了什么,我创建了以下示例:Clojure还原程序未按预期调用联合函数,clojure,parallel-processing,Clojure,Parallel Processing,我正在使用clojure reducers库进行实验,对于何时将合并函数作为reducers/fold函数的一部分进行调用,我有点困惑。为了查看何时调用了什么,我创建了以下示例: (def input (range 1 100)) (defn combine-f ([] (println "identity-combine") 0) ([left right] (println (str "combine " left " " right)) (max
(def input (range 1 100))
(defn combine-f
([]
(println "identity-combine")
0)
([left right]
(println (str "combine " left " " right))
(max (reduce max 0 left)
(reduce max 0 right))))
(defn reduce-f
([]
(println "identity-reduce")
0)
([result input]
(println (str "reduce " result " " input))
(max result input)))
(clojure.core.reducers/fold 10 combine-f reduce-f input)
;prints
identity-combine
reduce 0 1
reduce 1 2
reduce 2 3
reduce 3 4
.
.
.
reduce 98 99
我希望当fold执行时,输入将被分成大小大约为10的组,每个组使用reduce-f进行缩减,然后使用combine-f进行组合。但是,在运行上述代码时,似乎联合函数仅作为标识调用一次,并且使用reduce-f减少了整个输入。有人能解释我为什么看到这种行为吗
谢谢
马特。不幸的是,
范围目前无法并行实现。按原样,在范围内折叠
将始终像直线减少
一样进行,联合收割机操作员的身份呼叫除外。作为比较,向量提供随机访问,因此是可折叠的:
(def input (vec (range 1 50)))
(defn combine-f
([]
(println "identity-combine")
Long/MIN_VALUE)
([left right]
(println (str "combine " left " " right))
(max left right)))
(defn reduce-f
([]
(println "identity-reduce")
Long/MIN_VALUE)
([result input]
(println (str "reduce " result " " input))
(max result input)))
(clojure.core.reducers/fold 10 combine-f reduce-f input)
输出:
identity-combineidentity-combineidentity-combine
reduce -9223372036854775808 1
reduce -9223372036854775808 25reduce -9223372036854775808 19
reduce -9223372036854775808 13reduce 25 26
reduce 26 27
reduce 1 2
reduce 27 28
reduce 28 29
reduce 29 30
reduce 2 3
reduce 19 20
reduce 3 4
identity-combinereduce 4 5
reduce 5 6reduce 13 14
reduce 14 15
reduce 20 21identity-combine
reduce 21 22
reduce 15 16
reduce -9223372036854775808 31
reduce 22 23reduce 16 17reduce -9223372036854775808 7
reduce 7 8
reduce 8 9
reduce 23 24
reduce 31 32
reduce 17 18
reduce 9 10
reduce 10 11
reduce 11 12
identity-combine
reduce 32 33
combine 18 24
combine 6 12identity-combine
reduce -9223372036854775808 37
reduce 33 34
reduce 37 38reduce -9223372036854775808 43
combine 12 24
reduce 43 44reduce 34 35reduce 38 39
reduce 44 45
reduce 35 36
reduce 45 46
reduce 39 40
reduce 46 47
combine 30 36
reduce 47 48
reduce 48 49
reduce 40 41
reduce 41 42
combine 42 49
combine 36 49
combine 24 49
您可能会注意到,由于对*out*
的非序列化访问,这一点更加混乱
(我需要稍微修改一下combine-f
,因为它试图在一段时间内减少。切换到long/MIN\u值对本例影响不大,但它是max
的标识元素,所以我想为什么不呢?) 谢谢你。我没想到这个范围不知道如何折叠自己。是否有任何简单的方法可以确定任何seq/集合是否可折叠?我看不到可折叠的?不幸的是,API中的函数。我不这么认为。有(满足?clojure.core.reducers/CollFold x)
,但它不是非常有用。我怀疑范围
就是在这里得到它的实现的。看起来主要是IPersistentVector和PersistentHashmap。