# Why does add-assign to Ref{Float64} allocate?

**URL:** <https://discourse.julialang.org/t/why-does-add-assign-to-ref-float64-allocate/96767>\
**Category:** Performance\
**Tags:** question, memory-allocation, ordinarydiffeq\
**Created:** [March 29, 2023, 9:46am UTC](https://discourse.julialang.org/t/why-does-add-assign-to-ref-float64-allocate/96767 "2023-03-29T09:46:55Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![AlexanderNenninger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexandernenninger/32/24602_2.png) [@AlexanderNenninger](https://discourse.julialang.org/u/AlexanderNenninger)\
**Post date:** [March 29, 2023, 9:46am UTC](https://discourse.julialang.org/t/why-does-add-assign-to-ref-float64-allocate/96767/1 "2023-03-29T09:46:55Z")

</div>

While optimizing some ODE code, I noticed that `+=` on `Ref{Float64}` allocates, while `.+=` on a vector slice doen’t. Why is that?

I wasn’t able to reproduce the effect without `DifferentialEquations`, but I feel like it should be possible.  
In practice I’m using `Params` for preallocation. Is that the correct design decision?

```julia
using Revise
using DifferentialEquations

struct Params
    x::Ref{Float64}
end

Params() = Params(0.0)

function f!(du::Vector{Float64}, u::Vector{Float64}, p::Params, t::Float64)
    p.x[] += 1.0 # 3168 bytes allocated
    du[1] = -u[1]
end

function run()
    u0 = [1.0]
    tspan = (0.0, 1.0)
    p = Params(0.0)
    ode_problem = ODEProblem(f!, u0, tspan, p)
    _ = solve(ode_problem, Tsit5(), reltol=1e-8, abstol=1e-8)
    println(p)
end

run()

```

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [March 29, 2023, 9:50am UTC](https://discourse.julialang.org/t/why-does-add-assign-to-ref-float64-allocate/96767/2 "2023-03-29T09:50:29Z")

</div>

`Ref` is an abstract type. Use `RefValue` in your struct definition instead.

---

<div class="post-metadata">

**Author:** ![AlexanderNenninger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexandernenninger/32/24602_2.png) [@AlexanderNenninger](https://discourse.julialang.org/u/AlexanderNenninger)\
**Post date:** [March 29, 2023, 12:40pm UTC](https://discourse.julialang.org/t/why-does-add-assign-to-ref-float64-allocate/96767/3 "2023-03-29T12:40:08Z")

</div>

Thanks, worked. Is there canonical documentation on abstract types as struct fields?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 29, 2023, 12:50pm UTC](https://discourse.julialang.org/t/why-does-add-assign-to-ref-float64-allocate/96767/4 "2023-03-29T12:50:57Z")

</div>

> [@AlexanderNenninger](#):
>
> Is there canonical documentation on abstract types as struct fields?

See the [Performance tips: Avoid fields with abstract type](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-type).
