It seems like f -= a
is actually exactly equivalent to f = f - a
. This surprised me because I’d naively expected -=
to be update-in-place, so that I wouldn’t need a View
when f
is an Array slice, but actually it seems I do:
julia> f = rand(3, 241, 2);
julia> a = rand(241);
julia> function update!(f, a, i, k)
@. f[i,:,k] -= a
end
update! (generic function with 1 method)
julia> function update_view!(f, a, i, k)
@. @view(f[i,:,k]) -= a
end
update_view! (generic function with 1 method)
julia> function update_view2!(f, a, i, k)
@. f[i,:,k] = @view(f[i,:,k]) - a
end
update_view2! (generic function with 1 method)
julia> @time update!(f, a, 1, 1);
0.235987 seconds (440.13 k allocations: 25.313 MiB, 8.33% gc time, 99.98% compilation time)
julia> @time update!(f, a, 1, 1);
0.000007 seconds (2 allocations: 2.047 KiB)
julia> @time update_view!(f, a, 1, 1);
0.162541 seconds (326.76 k allocations: 18.569 MiB, 99.98% compilation time)
julia> @time update_view!(f, a, 1, 1);
0.000006 seconds (1 allocation: 64 bytes)
julia> @time update_view2!(f, a, 1, 1);
0.067399 seconds (27.27 k allocations: 1.185 MiB, 99.96% compilation time)
julia> @time update_view2!(f, a, 1, 1);
0.000006 seconds (1 allocation: 64 bytes)
So update!
requires allocations (I guess it compiles to something equivalent to update_view2!
, but without the @view
on the right hand side?), while update_view!
and update_view2!
are essentially identical.
In hindsight this makes some sense, but I find it surprising that I need @view
on the left hand side of an ‘assignment’ operator. So two questions: Is this expected behaviour? Is it worth giving a warning (edit: I mean a warning in the documentation of -=
, etc somewhere) about this behaviour of -=
(and I assume +=
, etc. are similar)? Although maybe there is a warning somewhere and I just didn’t look hard enough (apologies if so).