6
votes

I'm wondering why the code below provides no speedup in the case of r/fold? Am I misunderstanding something about reducers?

I'm running it on a pretty slow (although with 2 cores) Ubuntu 12.04 dev box, both through emacs and lein run, each with the same results.

(require '[clojure.core.reducers :as r])
(.. Runtime getRuntime availableProcessors)

;; 2

(let
  [n 80000000
   vs #(range n)]

  (time (reduce + (vs)))
  (time (r/fold + (vs)))

"Elapsed time: 26076.434324 msecs"
"Elapsed time: 25500.234034 msecs"

Thanks.

1

1 Answers

9
votes

You are folding over a seq. Parallel fold only happens on persistent vectors and maps right now.

There are also all sorts of reasons why this kind of perf testing is inferior to using something like Criterium, but that's probably a separate discussion. (Some of the reasons are garbage collection, JVM warmup and inlining, funky default jvm settings on both Emacs and lein, boxed and checked math, etc.)

Still wrong for many of the above reasons but slightly more useful comparison:

(require '[clojure.core.reducers :as r])
(def v (vec (range 800000)))
(dotimes [_ 100] (time (reduce + v)))
(dotimes [_ 100] (time (r/fold + v)))

Watch the best times from each of the last 2 runs.