调整clojure reducers库性能

FUD*_*FUD 6 clojure reducers

为什么使用reducers库进行映射/缩减比普通map/reduce更差?

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)
Run Code Online (Sandbox Code Playgroud)

我有两个杀了后两个,因为它无限期地长.这有什么不对?

编辑: 似乎其他语言也有类似的问题.斯卡拉似乎只打破了一百万.为什么Scala并行集合有时会导致OutOfMemoryError?.虽然减速器比百万减速器快一般.

cgr*_*and 6

为了补充@ a-webb的答案,这是一个编译器错误,并且是一个真正解决的问题.(有关详细信息,请参阅此帖子.)

解决这个问题的另一种方法是使用保险丝:

(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))))))
Run Code Online (Sandbox Code Playgroud)

然后:

=> (time (r/reduce + (r/map inc (once-seq (range 100000000)))))
"Elapsed time: 3692.765 msecs"
5000000050000000
Run Code Online (Sandbox Code Playgroud)