Clojure reducers - effectively apply a function to two vectors in parrallel

What is the most efficient and idiomatic way to combine two or more large vectors? This is what I did. In my application, I use matrices, so each operation is a bit more expensive than adding two paired. Using range to control crease seems a bit awkward.

 (require '[clojure.core.reducers :as r]) (def a (mapv (fn [_] (rand 100)) (range 100000))) (def b (mapv (fn [_] (rand 100)) (range 100000))) (r/foldcat (r/map #(+ (a %) (b %)) (range (count a)))) 

It is also calculated that range may turn out to be the most expensive bit for multi-core CPUs, since it is the only non-parallel part and includes sequences.

+5
source share
1 answer

Actually it looks like this: Clojure 1.8 has a pretty good answer, and the template is already in Clojure 1.7 using map-index .

Ideally, I need a map-index that accepts several collections, such as map , but this will be done. It looks pretty clojuresque, unlike my kludgy fold on the range.

 (defn combine-with [op a-coll] (fn [i b-el] (op (a-coll i) b-el))) (map-indexed (combine-with + a) b) 

You just have to wait 1.8 for performance: http://dev.clojure.org/jira/browse/CLJ-1553

Below are some timings for a 6-core processor:

 (def irange (vec (range (count a)))) ; precompute (c/quick-bench (def ab (r/foldcat (r/map #(+ (a %) (b %)) irange)))) Execution time mean : 1.426060 ms (c/quick-bench (def abt (into [] (map-indexed (combine-with + a)) b))) Execution time mean : 9.931824 ms 
0
source

All Articles