How to initialize an array inside a struct in Julia?

Viewed 275

I am new to Julia. The following code is tested to initialize arrays inside a struct.

struct Foo
  alpha :: Array{Float64,2}
  beta  :: Array{Float64,2}
  
  function Foo(nrow::Int,ncol::Int)
    new( zeros(Float64, nrow, ncol),
      zeros(Float64, nrow, ncol) );
  end

end

f1 = Foo(3,3)

println(f1.beta)

where, the sizes of arrays inside a struct is not determined until running. I wonder if this is the correct way ( especially with regard to performance ) to allocate memory for alpha and beta.

2 Answers

Your code is spending some time filling the allocated Matrix with zeros, a faster version would be:

struct Foo
  alpha :: Array{Float64,2}
  beta  :: Array{Float64,2}  
  function Foo(nrow::Int,ncol::Int)
    new( Matrix{Float64}(undef, nrow, ncol),
      Matrix{Float64}(undef, nrow, ncol) );
  end
end

This of course results with some data being present in your array in the beginning.

You can consider making the size of your object to be a part of its type definition:

Base.@kwdef struct Foo2{N,M}
  alpha::Array{Float64,2} = zeros(Float64, N, M)
  beta::Array{Float64,2} = zeros(Float64, N, M)
end

Note that I used Base.@kwdef to generate a constructor which results in shorter code. I used zeros for readability, however undef constructor can be used in similar way as in the example above.

This struct can be simply used as:

julia> Foo2{2,3}()
Foo2{2, 3}([0.0 0.0 0.0; 0.0 0.0 0.0], [0.0 0.0 0.0; 0.0 0.0 0.0])

The above "store my size in type" approach is more about the style rather than performance, unless you start writing code that makes an actual use of this information.

The easiest way to start is through StaticArrays:

using StaticArrays
Base.@kwdef struct Foo3{N,M}
  alpha::MMatrix{N,M,Float64} = MMatrix{N,M}(zeros(Float64, N, M))
  beta::MMatrix{N,M,Float64} = MMatrix{N,M}(zeros(Float64, N, M))
end

This struct again can be used as:

julia> Foo3{2,3}()
Foo3{2, 3}([0.0 0.0 0.0; 0.0 0.0 0.0], [0.0 0.0 0.0; 0.0 0.0 0.0])

Static arrays are much faster but they take a significant type to compile. Basically it makes sense to use them for arrays having up to something like 50 elements.

Yes, it is.

If you really worry that the size is not determined until running, you can take a look at StaticArrays.jl

Related