Clojure redurs fold不会按预期调用组合函数

时间:2015-11-01 19:34:18

标签: clojure parallel-processing

我正在尝试使用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减少。谁能解释为什么我会看到这种行为?

谢谢,

1 个答案:

答案 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的身份元素是多头,所以我想为什么不呢?)。