# Pre-allocation for matrices / vectors of matrices of different length

Hi all,

I am doing a bunch of simulations, and I want to save the outcome of these `N` simulations
My parameters for each simulation is a `p ` of type `Vector{Matrix{Float32}}`, and there are `M` vectors `X, Y` that I’d like to store for each `p`.
The dimensions of `p`, `X`, and `Y` are known a priori.

Currently I’m doing something along the lines of

``````data = Dict()
X_dim = ... # lenght of X
Y_dim = ... # length of Y
for i in 1:N
p = generate_params()
Xs = Matrix{Float32}(undef, M, X_dim)
Ys = Matrix{Float32}(undef, M, Y_dim)
for j in 1:M
X = rand(X_dim)
Y = simulation(X, p)
Xs[j, :] .= X
Ys[j, :] .= Y
end
merge!(dict, i => (p = p, Xs = Xs, Ys = Ys))
end
``````

to store the data.
But (unsurprisingly) this leads to a lot of garbage collection time, and I’m wondering if there is a good way of preallocating memory to speed things up.
I suspect there must be, as all dimensions are known, but I can’t figure out an elegant way to do it that still keeps track of all the data easily!

Do you really need a dictionary if all you are doing is indexing simulations with `i in 1:N`? Why not a vector of matrices?

It seems to me that the only allocations that can be avoided are `X` and `Y`.

You need to allocate `N` instances of `p`, `Xs`, and `Ys` b/c you store those.
Assigning them to the `Dict` does not allocate. Though I don’t know how `merge!` operates. `d[i] = (p = p, Xs = Xs, Ys = Ys)` would seem easier anyway.

To avoid allocating `X` and `Y`, in your loop:

``````@views for j = 1 : M
Xs[j,:] .= rand(X_dim)
Ys[j,:] .= simulation(Xs[j,:], p)
# or simulation!(Ys[j,:], Xs[j,:], p)
end
``````

You could even do `rand!(Xs[j,:])`