You called it pfrequencies
, which, along with your parallel-processing
tag on the question, suggests you think that something is using multiple threads here. That is not the case, and neither is it the "main" goal of the reducers library.
The main thing reducers buy you is that you don't need to allocate many intermediate cons cells for your lazy sequences. Before reducers were introduced, frequencies
would allocate 10000000 cons cells to create a sequential view of the vector for reduce
to use. Now that reducers exist, vectors know how to reduce themselves without creating such temporary objects. But that feature has been backported into clojure.core/reduce
, which behaves exactly like r/reduce
(ignoring some minor features that are irrelevant here). So you are just benchmarking your function against an identical clone of itself.
The reducers library also includes the notion of a fold
, which can do some work in parallel, and then later merge together the intermediate results. To use this, you need to provide more information than reduce
needs: you must define how to start a "chunk" from nothing; your function must be associative; and you must specify how to combine chunks. A. Webb's answer demonstrates how to use fold
correctly, to get work done on multiple threads.
However, you're unlikely to get any benefit from folding: in addition to the reason he notes (you give up transients, compared to clojure.core/frequencies
), building a map is not easily parallelizable. If the bulk of the work in frequencies
were addition (as it would be in something like (frequencies (repeat 1e6 1))
), then fold
would help; but most of the work is in managing the keys in the hashmap, which really has to be single-threaded eventually. You can build maps in parallel, but then you have to merge them together; since that combination step takes time proportional to the size of the chunk, rather than constant time, you gain little by doing the chunks on a separate thread anyway.
fold
notreduce
as it is almost same as core reduce – Ankurfold
version on 2 cores will probably be still be much slower than theclojure.core/frequencies
version which uses transients. – A. Webb