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.
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.
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}: ...
Just collecting the answers and comments from other users in a single post:
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 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.
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 Int
s 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With