为什么使用减速器映射/减少库的性能比普通地图/减少更差?

user=> (time (reduce + (map inc (range 100000000))))
"Elapsed time: 14412.627966 msecs"
5000000050000000

user=> (time (reduce + (r/map inc (range 100000000))))
... (C-c)

user=> (time (r/reduce + (r/map inc (range 100000000))))
....(C-c)
.

我有两次杀死后来,因为它无限期地需要。这里有什么问题?

编辑: 似乎其他语言也有类似的问题。Scala似乎只爆发了一百万。 Scala并行集合有时会导致OutofMemoryError?。虽然Clojure Reducers比百万的正常水平更快。

有帮助吗?

解决方案

补充@ a-webb的答案,这是一个编译器错误,涉及一个真正修复。(有关更多详细信息,请参阅此帖子。

解决问题的另一种方法是使用 fuse

(defn once-seq
  "Returns a sequence on which seq can be called only once."
  [coll]
  (let [a (atom coll)]
    (reify clojure.lang.Seqable
      (seq [_]
        (let [coll @a]
          (reset! a nil)
          (seq coll))))))
.

然后:

=> (time (r/reduce + (r/map inc (once-seq (range 100000000)))))
"Elapsed time: 3692.765 msecs"
5000000050000000
.

其他提示

性能磨削以停止,因为内存被耗尽。如果您继续等待,您很可能会遇到内存错误。创建减速器将收集的头部保持在关闭中。因此,巨大的惰性序列在实现时结束内存。

这是发生的事情,蒸馏出来

user=> (def n 100000000)
#'user/n

user=> (time (dorun (range n)))
"Elapsed time: 12349.034702 msecs"
.

现在是一样的,但从封闭中......

user=> (defn foo [x] (fn [f] (f x)))
#'user/foo

user=> (time ((foo (range n)) dorun))
OutOfMemoryError GC overhead limit exceeded ... (sometime later)
.

比较

(time (do (doall (range n)) nil))
OutOfMemoryError GC overhead limit exceeded ... (sometime later)
.

减速器中的嫌疑人关闭

user=> (source r/folder)
(defn folder
  "Given a foldable collection, [...]"
  {:added "1.5"}
  ([coll xf]
     (reify
      clojure.core.protocols/CollReduce
      (coll-reduce [_ f1]
                   (clojure.core.protocols/coll-reduce coll (xf f1) (f1)))
   ...
.

christophe grand 有一个 nofoling 如何以懒惰的方式撰写减速器。

Reducers与懒惰列表实际上并没有很好地运行,而正常减少则延迟。

为了从减速器中获得真正的好处,您需要一个非懒惰的集合,例如,向量,您需要使用折叠而不是减少。

 (def v (into [] (range 10000000)))
 (time (reduce + (map inc v)))
 ;; "Elapsed time: 896.79 msecs"
 (time (reduce + (r/map inc v)))
 ;; "Elapsed time: 671.947 msecs" 
 (time (r/fold + (r/map inc v)))
 ;; "Elapsed time: 229.45 msecs"
.

减速器与Fork / Join Framework一起工作,需要大块数据。在懒惰(块)序列中,您没有这些大块,所以fork /加入无法正常工作。

在解释概念的减速器上有富豪的富豪谈话真的很好: https://vimeo.com/45561411

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top