Why is this in-place assignment allocating more memory?

Viewed 50

I am trying to understand memory management a little better. I have the following example code:

begin 
    mutable struct SimplestStruct
        a::Float64
    end
    
    function SimplestLoop!(a::Array{SimplestStruct, 1}, x::Float64)
        for i in 1:length(a)
            @inbounds a[i].a = x
        end
    end
    
    simples = fill(SimplestStruct(rand()), 100)
    
    @time SimplestLoop!(simples, 6.0)
end

As far as I can work out from the docs + various good posts around about in-place operations, SimplestLoop! should operate on its first argument without allocating any extra memory. However, @time reports 17k allocations.

Is there an obvious reason why this is happening?

Thank you in advance!

1 Answers

If you perform the @time measurement several times, you'll see that the first measurement is different from the others. This is because you're actually mostly measuring (just-ahead-of-time) compilation time and memory allocations.

When the objective is to better understand runtime performance, it is generally recommended to use BenchmarkTools to perform the benchmarks:

julia> using BenchmarkTools

julia> @btime SimplestLoop!($simples, 6.0)
  82.930 ns (0 allocations: 0 bytes)

BenchmarkTools's @btime macro takes care of handling compilation times, as well as averaging runtime measurements over a sufficiently large number of samples to get accurate estimations. With this, we see that there are indeed no allocations in your code, as expected.

Related