# Type inference difference in \`mapreduce(f, op, t)\` vs \`reduce(op, map(f, t))\`

**URL:** https://discourse.julialang.org/t/type-inference-difference-in-mapreduce-f-op-t-vs-reduce-op-map-f-t/93265
**Category:** Performance
**Tags:** inference, type-stability
**Created:** [January 20, 2023, 2:26pm UTC](https://discourse.julialang.org/t/type-inference-difference-in-mapreduce-f-op-t-vs-reduce-op-map-f-t/93265 "2023-01-20T14:26:09Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)
#### Post date: [January 20, 2023, 2:26pm UTC](https://discourse.julialang.org/t/type-inference-difference-in-mapreduce-f-op-t-vs-reduce-op-map-f-t/93265/1 "2023-01-20T14:26:09Z")

</div>

For tuples, it seems `mapreduce` has poorer type inference than `map` + `reduce`.

```julia
julia> using FillArrays, Infinities, InfiniteArrays, Test

julia> ax = Ones{Int}(InfiniteCardinal{0}());

julia> y = (ax,ax);

julia> @inferred (t -> mapreduce(sum, *, t))(y)
ERROR: return type InfiniteCardinal{0} does not match inferred return type Any
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] top-level scope
   @ REPL[6]:1

julia> @inferred (t -> reduce(*, map(sum, t)))(y)
ℵ₀

```

This is perhaps because `map` is specialized for tuples. Is this an instance where code\_warntype isn’t accurate, and the result is correctly inferred in both cases? Or is it better to replace `mapreduce` by `map` + `reduce`?

---

<div class="post-metadata">

### Author: ![jlewisk](https://avatars.discourse-cdn.com/v4/letter/j/bc79bd/32.png) [@jlewisk](https://discourse.julialang.org/u/jlewisk)
#### Post date: [October 24, 2024, 8:42am UTC](https://discourse.julialang.org/t/type-inference-difference-in-mapreduce-f-op-t-vs-reduce-op-map-f-t/93265/2 "2024-10-24T08:42:21Z")

</div>

Ran into a similar problem when constructing a Turing.jl model. Has anyone resolved why this is the case. I created another example where it can arise (but note that this does not match the “red” result on @code\_warntype I recieved during the model run)

```julia
using Random

function test_arr_fn(n)   
    y = map(i -> rand(1:100, n), 1:n)
    z = mapreduce(x -> x.^2, hcat, y)
    return z
end

@code_warntype test_arr_fn(10)

function test_arr_fn2(n)   
    y = map(i -> rand(1:100, n), 1:n)
    z = reduce(hcat, map(x -> x.^2, y))
    return z
end

@code_warntype test_arr_fn2(10)

using OrdinaryDiffEq

function lorenz!(du, u, p, t)
    du[1] = 10.0 * (u[2] - u[1])
    du[2] = u[1] * (28.0 - u[3]) - u[2]
    du[3] = u[1] * u[2] - (8 / 3) * u[3]
end

u0 = [1.0; 0.0; 0.0]
tspan = (0.0, 100.0)

function test_ode_fn(model, u0, tspan) 
    prob = ODEProblem{true}(model, u0, tspan)
    sol = solve(prob)
    sol_red = mapreduce(x -> x .+ 2, hcat, sol.u)
    return sol_red
end

@code_warntype test_ode_fn(lorenz!, u0, tspan)

function test_ode_fn2(model, u0, tspan) 
    prob = ODEProblem{true}(model, u0, tspan)
    sol = solve(prob)
    sol_red = reduce(hcat, map(x -> x .+ 2, sol.u))
    return sol_red
end

@code_warntype test_ode_fn2(lorenz!, u0, tspan)

```

Perhaps this is because hcat could return objects of different shapes?
