使用core.reducers时的性能提升

mur*_*a52 0 clojure

我在下面尝试比较了core / map与换能器vc core.reducers / map与core.reducers / fold的性能-

    (time (->> (range 10000)
            (r/map inc)
            (r/map inc)
            (r/map inc)
            (into [])))

;; core.reducers/map
;; "Elapsed time: 3.962802 msecs"


(time (->> (range 10000)
            vec
            (r/map inc)
            (r/map inc)
            (r/map inc)
            (r/fold conj)))

;; core.reducers/fold
;; "Elapsed time: 3.318809 msecs"


(time (->> (range 10000)
            (map inc)
            (map inc)
            (map inc)))

;; core/map
;; "Elapsed time: 0.148433 msecs"



(time (->> (range 10000)
            (sequence (comp (map inc)
                         (map inc)
                         (map inc)))))

;; transducers
;; "Elapsed time: 0.215037 msecs"
Run Code Online (Sandbox Code Playgroud)

1)我的期望是核心/映射的时间最多,但是时间最短。当没有为换能器创建中间序列时,为什么它比换能器性能更好,并且换能器应该更快?

2)为什么core.reducers / fold版本没有比core.reducers / map版本快很多,它是否应该并行化操作?

3)为什么core.reducers版本比懒惰的版本慢,整个序列最终都实现了,所以渴望的评估不应该比懒惰的版本更高效吗?

ama*_*loy 5

  1. map是惰性的,因此使用core / map的测试用例根本无法工作。尝试doall收集(或into []),我希望它毕竟是最慢的。您可以通过将10000更改为1e12来使自己相信这一点,并观察到,如果您的计算机可以像处理一万个元素一样快地处理一万亿个元素,那么它就不必为每个元素做很多工作!
  2. 有什么要并行化的?此操作最昂贵的部分不是对的调用inc(并行化),而是在最后将结果组合到向量中(不能)。尝试使用更昂贵的功能,例如#(do (Thread/sleep 500) (inc %)),您可能会看到不同的结果。
  3. 这不是与(1)相同的问题吗?

  • @ murtaza52花费时间后,_real_被实现(时间返回延迟序列,然后您的REPL意识到)。同样,如果您使用终端/ ide / editor / ...的输出功能,并将其也包括在测量中,则很可能会看到错误和误导性的结果。确保找到的结果在那里(例如,获取最后一个元素),但不要测量终端在打印多行时的状况。 (2认同)