我正在尝试使用clojure redurs库,我对于何时将combine函数作为reducers / fold函数的一部分调用时有点困惑。为了看到什么时候被调用,我创建了以下示例:
(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
我期待折叠执行时,输入将被分区为大小为10的组,每组使用reduce-f减少,然后使用combine-f进行组合。无论运行上面的代码,似乎组合函数只被调用一次作为标识,整个输入使用reduce-f减少。谁能解释为什么我会看到这种行为?
谢谢,
太
答案 0 :(得分:1)
不幸的是,range
目前无法并行实现。 It seems there are foldable implementations around as an enhancement ticket, but I can't seem to find right now why they haven't been accepted.按原样,fold
上的range
将始终像直线reduce
一样进行,但对联合运营商的身份调用除外。为了比较,矢量提供随机访问,因此是可折叠的:
(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
,因为它正在尝试reduce
超过一个长时间。切换到Long/MIN_VALUE
不会影响此示例但是max
的身份元素是多头,所以我想为什么不呢?)。