Code uses excessive memory when using ```.+``` instead of a loop?

In debugging some code I wrote, I noticed that there seems to be a significant difference between x = x .+ 1 and writing the loop out explicitly. In particular, the following code runs in 0.006 seconds and reports only 2 allocations totaling 64KiB.

function main()
    N = 5000
    M = 2^13
    x = zeros(M)
    for _ in 1:N
        for j in 1:M
            x[j] = x[j] + 1
        end
        #x = x .+ 1
    end
end

@time main()

However, if I uncomment the line x = x .+ 1, the code runs in 0.3 seconds and reports 10k allocations totaling 300 MiB. Moreover, if I increase N to 20000 the memory usage increases to 1.2GiB – the array does not change size just the number of iterations. Why is the memory usage so large? Should I avoid using broadcasting in loops for this reason? I assume I am making some fundamental mistake.

If it helps, I am using julia version 1.9.3.

You want x .= x .+ 1. This modifies x in-place. Whereas x = x .+ 1 allocates a new array and then assigns it to x.

9 Likes

Excellent! Thank you so much, that fixes the problem.

1 Like

Small note–using for j in 1:M is generally bad practice, because it’s slower and more error-prone than for j in eachindex(x). It causes bugs when the array indices aren’t 1:M. (Here they are so it’s OK, but that’s not always the case, so avoiding ranges is a good habit.)

1 Like