# Reducing allocations

**URL:** <https://discourse.julialang.org/t/reducing-allocations/129415>\
**Category:** New to Julia\
**Tags:** memory-allocation\
**Created:** [May 28, 2025, 4:11pm UTC](https://discourse.julialang.org/t/reducing-allocations/129415 "2025-05-28T16:11:51Z")\
**Posts on this page:** 5\
**Page:** 3

<div class="post-metadata">

**Author:** ![tverho](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tverho](https://discourse.julialang.org/u/tverho)\
**Post date:** [May 31, 2025, 1:56pm UTC](https://discourse.julialang.org/t/reducing-allocations/129415/41 "2025-05-31T13:56:19Z")

</div>

The `Atoms` type seems to be an example of something I often have in my codes, i.e. a struct representing the data and the state of the whole model. Most fields are vectors that are obviously mutable (or, rather, their contents are), but some fields are scalars or SVectors/SMatrices that are not mutable. It is natural to make them mutable as well and I don’t think it is a problem. A straightforward way is to make the whole struct mutable. Mutable types are not automatically less performant than immutable. Mutability prevents certain types of optimizations and vectors of mutable types are not stored in memory the same way as immutable types, but in this case I would first check if there’s any performance difference if you make `Atoms` mutable. Another way I’ve sometimes used is to use `Ref` so that they are stored as references and can be changed (and your refer to them as `atoms.lvecs[]`). A third way is to use Accessors.jl.

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [May 31, 2025, 2:25pm UTC](https://discourse.julialang.org/t/reducing-allocations/129415/42 "2025-05-31T14:25:31Z")

</div>

I guess I don’t see the benefit of using a mutable `struct` if I can make the struct’s fields mutable. (e.g.`atoms.positions` is mutable, why does `atoms` need to be mutable?)

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 31, 2025, 2:38pm UTC](https://discourse.julialang.org/t/reducing-allocations/129415/43 "2025-05-31T14:38:10Z")

</div>

Depending on the computations, what might be a significant improvement is to store the coordinates, for example, of all atoms, as a vector of SVectors.

(For instance considering the StructArrays.jl package)

But all these considerations should worry you after eliminating the allocations in critical parts of the code, using mutable data or not. Then, further optimizations should be very focused and based on profiling.

Another thing is that you can use MMatrix as intermediates for conveniently “updating” an SMatrix, if the function does not escape the mutable object:

```julia-repl
julia> function modify_smatrix(S)
           M = MMatrix(S)
           for _ in 1:1000
               for j in 1:3, i in 1:3
                   M[i,j] = rand()  
               end
           end
           return SMatrix(M)
       end
modify_smatrix (generic function with 1 method)

julia> @btime modify_smatrix!($(rand(SMatrix{3,3,Float64})))
  6.476 μs (0 allocations: 0 bytes)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
 0.288959 0.527593 0.839765
 0.556196 0.0926586 0.96533
 0.0807712 0.800752 0.775332

```

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [May 31, 2025, 3:10pm UTC](https://discourse.julialang.org/t/reducing-allocations/129415/44 "2025-05-31T15:10:51Z")

</div>

> [@lmiq](#):
>
> Depending on the computations, what might be a significant improvement is to store the coordinates, for example, of all atoms, as a vector of SVectors.

I am doing this.

```julia
struct atoms
    title::String
    latpar::Float64
    lVecs::MMatrix{3,3,Float64,9}
    coordSys::Vector{String} # 'D' for Direct or 'C' for cartesian
    positions:: Vector{SVector{3,Float64}} # List of all the atomic basis vector separated by type 
    velocities:: Vector{SVector{3,Float64}} # Velocities of the atoms
    masses:: Vector{Float64}
    atomTypes:: Vector{Int64} # Integers representing the type for each basis atom
    species:: Vector{String} # Species of the atoms 
    energies::MVector{2,Float64}
    lj_vec::Vector{Float64} # Vector of 1/r^6 and 1/r^12 values for each unique pair of atom types
end

```

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 31, 2025, 3:12pm UTC](https://discourse.julialang.org/t/reducing-allocations/129415/45 "2025-05-31T15:12:26Z")

</div>

> [@tverho](#):
>
> My instinct would be to avoid MMatrix because using them often doesn’t lead to the desired result (no allocations) and their behavior is not easy to reason about.

Well, I prefer to use MMatrix as default and only switch to SMatrix when I cannot get rid of allocations otherwise. For me, MMatrix and MVector are good enough to avoid allocations in most cases.

[Previous page](https://discourse.julialang.org/t/reducing-allocations/129415.md?page=2)
