tomtom
1
I’m wondered seeing that mapslices()
gives warntype as below:
julia> const mat = randn(3,2)
3×2 Array{Float64,2}:
1.49498 -1.98461
-0.935659 -0.0317199
0.783414 -0.284129
julia> mapslices(prod, mat, dims = 1)
1×2 Array{Float64,2}:
-1.09583 -0.0178864
julia> @code_warntype mapslices(prod, mat, dims = 1)
Body::Any
...
5 ┄ %16 = Base.:(var"#mapslices#109")(dims, @_3, f, A)::Any
└── return %16
is there any way to avoid the warntype? thanks.
Mapslices can’t be inferred, because Julia has no way of telling what prod
applied to a slice mat
looks like without trying. Therefore mapslices
first figures that out by calling prod
on the first slice and then it calls an inner function which then is “typestable”. [source]
See keyword “function barrier” in the [performance tips]. Therefore you do not need to worry much about that warning, are you calling mapslices
in highly performance relevant code or inner loops?
1 Like
mapslices
just doesn’t behave very well, IMO, and you are much better off building the same thing from other pieces. These are fine:
@code_warntype map(prod, eachcol(mat))
@code_warntype map(prod, eachslice(mat, dims=2)) # same, with keyword
although of course you can write prod(mat, dims=1)
, but I guess it’s an example. If your function returns arrays, you want something like this:
f(x) = vcat(x, x .^ 2)
mapslices(f, mat, dims=1) == reduce(hcat, map(f, eachcol(mat))) # true
@code_warntype mapslices(f, mat, dims=1) # Any
@code_warntype reduce(hcat, map(f, eachcol(mat))) # Array{Float64,2}
2 Likes
tomtom
4
yes, using in performance sensitive inner loop… so, even with the function barrier inner_mapslices!()
, seems like mapslices()
is still very slow compared to map( , eachcol() )
as suggested by @mcabbott:
julia> @btime prod($mat, dims = $1);
57.745 ns (1 allocation: 96 bytes)
julia> @btime map($prod, eachcol($mat));
76.787 ns (6 allocations: 256 bytes)
julia> @btime map($prod, eachslice($mat, dims = $2));
585.473 ns (7 allocations: 272 bytes)
julia> @btime mapslices($prod, $mat, dims = $1);
4.639 μs (54 allocations: 2.56 KiB)
it’s interesting to see that map( , eachslice())
is that much slower than map(, eachcol() )
!
another thing to note is the confusion of dims
: 1
is used in prod()
and mapslices()
but 2
should be used in eachslice()
!!!