On Tue, Oct 09, 2012 at 15:31 -0700, Jean Niklas L'orange wrote:
>On Tuesday, October 9, 2012 9:14:51 PM UTC+2, Wolodja Wentland wrote:
>
> --- snip ---
> (reduce-kv
> (fn [ret k v]
> (assoc ret k (func-that-does-something-with v)))
> some-map))
> --- snip --
>
> I am using reducers in other places, but am not entirely sure how to
> employ
> them here. I would be grateful for any advice.
>
>You could use merge as the combine function, and let (fn [ret [k
>v]] (assoc ret k (func-that-does-something-with v))) be the reducing
>function you pass to fold. Then it's at least parallelisable, though I'm
>unsure of its performance.
I played with the following implementation:
(defn update-vals
[m f]
(persistent!
(reduce-kv
(fn [ret k v]
(assoc! ret k (f v)))
(transient {})
m)))
(defn pupdate-vals
[m f]
(r/fold
(r/monoid merge hash-map)
(fn [ret [k v]]
(conj ret [k (f v)]))
(vec m)))
(defn foo
[x]
(Thread/sleep 0.2)
(inc x))
but unfortunately update-vals still outperforms pupdate-vals even on large
maps. I am not sure what else I can do to speed up folding into maps
(as opposed to a single value), but I'll keep on experimenting.
user=> (def m (zipmap (range 10) (range 10)))
#'user/m
user=> (time (dotimes [_ 100] (pupdate-vals m inc)))
"Elapsed time: 8068.950282 msecs"
nil
user=> (time (dotimes [_ 100] (update-vals m inc)))
"Elapsed time: 1106.253256 msecs"
nil
user=> (time (dotimes [_ 100] (pupdate-vals m foo)))
"Elapsed time: 8890.445481 msecs"
nil
user=> (time (dotimes [_ 100] (update-vals m foo)))
"Elapsed time: 3954.917294 msecs"
--
Wolodja
4096R/CAF14EFC
081C B7CD FF04 2BA9 94EA 36B2 8B7F 7D30 CAF1 4EFC
signature.asc
Description: Digital signature