How to reduce memory allocation when looping over an array?

Hi guys, I have one main question with a given example and a couple other ones related to understanding some concepts.

First, here’s the example function:

function brownian_paths(; paths=10^3, n=10^5, t=1, S0=100, μ=(S,k) -> 0.0S, σ=(S,k) -> 0.3S)
    Δ = t / n
    S = randn((n, paths)) 
    S[1,:] .= S0
    
    if n > 1
        for i = 2:n
            @. S[i,:] = S[i-1,:] + μ(S[i-1,:], (i-1)*Δ)*Δ + σ(S[i-1,:], (i-1)*Δ)*sqrt(Δ)*S[i,:]
        end
    end
    
    return S
end;

I know that I am allocating memory when I create the S array. But as far as I understand from Julia’s website, running the loop starting “@.” makes that whole line do operations in-place on the i-th row of S instead of having to create some new Arrays every time and then assign them to that row.

But instead I see that loop allocates a lot more memory. You can see how much by running the following instead:

using TimerOutputs

function brownian_paths(; paths=10^3, n=10^5, t=1, S0=100, μ=(S,k) -> 0.0S, σ=(S,k) -> 0.3S)
    reset_timer!()
    Δ = t / n
    @timeit "Initialize S" S = randn((n, paths))
    S[1,:] .= S0

    @timeit "Loop" begin
        if n > 1
            for i = 2:n
                @. S[i,:] = S[i-1,:] + μ(S[i-1,:], (i-1)*Δ)*Δ + σ(S[i-1,:], (i-1)*Δ)*sqrt(Δ)*S[i,:]
            end
        end
    end
    print_timer()
    return S
end;

Does anyone have any insight on why this is happening? Might be obvious but idk, been digging all day and couldn’t find an answer to this anywhere.

(If you have any roasts to this function go ahead :slight_smile: New to Julia and my first project is to re-code all my option pricing algorithms in it)

Your broadcasting works in-place but the slices on the right-hand-side of the assignment create copies. If you want non-allocating views you can use the @views macro (but you need version 1.5 to get zero allocations).

Furthermore, Julia Arrays are column-major, while this code works along the rows, so you are losing performance on that too.

3 Likes

That is great, makes sense and something I forgot when reading the doc

Thanks a lot about the columns over rows info too.

Edit: After updating to version 1.5 and adding @views in front of @. I do see a reduction in memory allocation needed, but I don’t get zero allocation from the loop still?