Both loop/recur and reduction/transduce via IReduce are similar in doing 
looping without consuming stack, building up an accumulated value, and not 
allocating memory. reduce/transduce always take an input collection - if 
that collection can be traversed via internal reduction or sequential 
iteration, then I would favor using reduce over loop/recur. 

Take for example a vector, which is possibly the most interesting case with 
the most options. In a loop/recur how are you going to walk through the 
vector's elements? The most obvious way is to using the sequential 
functions like first/next/rest. Importantly, rest is going to give you a 
sequence over the vector, not the vector itself, which will incur extra 
cost. That said, the vector sequence is really fast - as much of the time 
it's just walking through an internal array node bumping an index. Or you 
might do indexed lookups into the vector ala nth. Your "iteration" has less 
overhead but on each index you must re-traverse the nodes of the vector.

Compare to a vector doing internal reduce - this is effectively an internal 
iteration that walks through the nodes of the vector data structure, 
evaluating the reduction function on each item it finds. There is no seq 
overhead and no re-traversal.

It's hard for me to say which of these is fastest without benchmarking a 
particular case, and it will matter a lot how many things are in the vector 
(as that affects the cost of lookup by index). My suspicion is that usually 
the cost for any of these is dominated by the function being applied per 
element, not by the iteration method.

loop/recur is beneficial in cases where the iteration is not based on 
traversing a collection (could be incrementing a counter, evaluating a 
function, iterating an external resource, etc), or traverses multiple 
collections in parallel, or any other "not sequentially traversing a 
collection" use case. Additionally, loop/recur is the only way in Clojure 
to get a loop that retains long or double primitives throughout the loop so 
for hot math loops you should definitely prefer loop/recur.

Alex


On Friday, April 29, 2016 at 5:46:03 AM UTC-5, Camilo Roca wrote:
>
>
> I have been hearing a lot of Clojure's use of an internalReduce protocol, 
> which seems to speed up things when using reduce.
> Now the thing is that a lot of people also claim that tail-call-recursion 
> is also pretty fast, which lets me wondering:
>
> - if I could replace a loop/recur with an equivalent reduce/reduced 
> approach, do I see performance gains?
>
> Obviously the immediate answer is just "benchmark it", but so far I 
> haven't found an stable solution to this question. The benchmark seems to 
> go sometimes for loop/recur and some others for reduce/reduced. I also know 
> that when doing primitive math, loop/recur performs better than 
> reduce/reduced, but I was wondering in which cases (regardless of idiomatic 
> or nor) would a reduce approach be preferred over a loop/recur?
>
> Any thoughts on this?
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to