Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this Clojure Reducers r/fold provide no perf benefit?

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.

like image 253
Scott Klarenbach Avatar asked Oct 10 '14 01:10

Scott Klarenbach


1 Answers

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.

like image 138
Alex Miller Avatar answered Sep 28 '22 01:09

Alex Miller