Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize an array of structs in Julia

Tags:

julia

I would like to understand what shall I put instead of xxxxx to have a 1000 items array initialized with structs where a goes from 2000 to 3000 (i.e., index 1 of the array means a is 2000, index 2 of the array means a is 2001, and so on) and b is always zero.

struct MyStruct
    a
    b
end

myArray = Vector{MyStruct}( xxxxx , 1000)

I understand I can make a loop and individually assign the values, I am just wondering if there is something faster in Julia.

like image 664
M.E. Avatar asked Sep 16 '19 09:09

M.E.


People also ask

How do I add elements to an array in Julia?

Arrays are mutable type collections in Julia, hence, their values can be modified with the use of certain pre-defined keywords. Julia allows adding new elements in an array with the use of push! command.

How do you initialize a vector in Julia?

The easiest way to initialize them are probably list comprehensions, for example: julia> [[Vector{Float64}(undef, 4) for _ = 1:5] for _ = 1:6] 5-element Array{Array{Array{Float64,1},1},1}: ...


1 Answers

Just collecting the answers and comments from other users in a single post:

No, there is nothing faster than a loop in Julia

Unlike other scripting languages like Python and R, loops are fast in Julia. In fact, other "vectorized" operations, like broadcasting, are implemented in terms of Julia loops themselves. Thus, a fast solution could be:

function initialize_vector(range::AbstractRange)
    v = Vector{MyStruct}(undef, length(range))
    @inbounds for i in eachindex(range)
        v[i] = MyStruct(range[i], 0)
    end
    return v
end

Broadcasting is both fast and convenient

Broadcasting is almost, or sometimes just as fast as looping, and can often be more terse and convenient. In this case, the function initialize_vector above can be written:

initialize_vector(range::AbstractRange) = MyStruct.(range, 0)

Benchmarking shows that the two functions are almost the same in speed.

Remember to type the fields in your struct for faster code

Julia relies on accurate inference of types to create fast, specialized code. If the types of MyStruct.a and MyStruct.b can be anything, it's generally not possible to infer exactly what kind of operations should be performed on a MyStruct. Even in this case, where the compiler is able to infer that the types are Int, each MyStruct has to contain references to heap-allocated Ints instead of being stack-allocated. Thus, a 10x speedup is obtained from simply changing

struct MyStruct
    a
    b
end

to

struct MyStruct
    a::Int
    b::Int
end

If you want to the type of Mystruct.a and MyStruct.b to be able to vary, you can create a parametric MyStruct, like so:

struct MyStruct{T}
    a::T
    b::T
end
like image 54
Jakob Nissen Avatar answered Sep 28 '22 10:09

Jakob Nissen