# Mapreduce slower than sum

**URL:** <https://discourse.julialang.org/t/mapreduce-slower-than-sum/36046>\
**Category:** General Usage\
**Tags:** question\
**Created:** [March 16, 2020, 4:11pm UTC](https://discourse.julialang.org/t/mapreduce-slower-than-sum/36046 "2020-03-16T16:11:18Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![CFBaptista](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cfbaptista/32/9264_2.png) [@CFBaptista](https://discourse.julialang.org/u/CFBaptista)\
**Post date:** [March 16, 2020, 4:11pm UTC](https://discourse.julialang.org/t/mapreduce-slower-than-sum/36046/1 "2020-03-16T16:11:18Z")

</div>

I am comparing three approaches for a point-wise multiplication of a vector field and a scalar field, followed by a summation over all elements of the resulting vector field. I would like to know why the `mapreduce` approach allocates more than both the `sum ` and my own `prodsum` approaches?

I would expect the `mapreduce` approach to be equally performant as my own `prodsum` implementation and that the `sum` approach would be the least performant. As it turns out, my own implementation is the most efficient and the `mapreduce` approach is the least efficient.

```julia
using StaticArrays

function prodsum(x, y)
    v = x[1]*y[1]
    for i = 2:length(x)
        @inbounds v += x[i]*y[i]
    end
    return v
end

function test()
    n = 10000
    x = rand(SVector{3, Float64}, n)
    y = rand(Float64, n)

    @time sum(x .* y)
    @time mapreduce((a, b) -> a*b, +, x, y)
    @time prodsum(x, y)
end

test();
test();

```

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [March 16, 2020, 7:52pm UTC](https://discourse.julialang.org/t/mapreduce-slower-than-sum/36046/2 "2020-03-16T19:52:11Z")

</div>

`mapreduce(*, +, x, y)` dispatches to:

> <https://github.com/JuliaLang/julia/blob/0f1b1192735e1c05c5aa0eab85bef92250abe05c/base/reducedim.jl#L308>

which allocates a temporary array. Also, it seems that function arguments are not fully specialized. `mapfoldl(Base.splat(*), +, zip(x, y))` seems to be as fast as the hand-coded function.

---

<div class="post-metadata">

**Author:** ![CFBaptista](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cfbaptista/32/9264_2.png) [@CFBaptista](https://discourse.julialang.org/u/CFBaptista)\
**Post date:** [March 17, 2020, 8:25am UTC](https://discourse.julialang.org/t/mapreduce-slower-than-sum/36046/3 "2020-03-17T08:25:05Z")

</div>

Thanks for pointing out the dispatch and the allocation of a temporary array.

However, the performance on my machine is not the same. The `mapfodl` approach is consistently about 30% slower (for n = 10000) and also makes two allocations which the hand-coded function does not.
