I am creating a simulator, and to avoid passing on several different arrays (with different datatypes) to other functions that will apend values to them, i was thinking about grouping the arrays inside a mutable struct, so i can pass the struct and work on the arrays inside the function.
So i went to test the performance of changing an array in different ways and inside or outside mutable structs and i came up with a bunch of doubts.
mutable struct Test_struct
b::Array{Int64}
end
function test0()
b = Array{Int64}(undef, 4, 1000000)
x = Vector{Int64}(undef, 4)
for i = 1:1000000
x = [i; 2*i; i; 2*i]
b[:,i] = x
end
end
function test1()
b = Array{Int64}(undef, 4, 1000000)
x = Vector{Int64}(undef, 4)
for i = 1:1000000
x = [i; 2*i; i; 2*i]
b[1,i], b[2,i], b[3,i], b[4,i] = x
end
end
function test2()
b = Array{Int64}(undef, 4, 1000000)
a = Test_struct(b)
x = Vector{Int64}(undef, 4)
for i = 1:1000000
x = [i; 2*i; i; 2*i]
a.b[1,i], a.b[2,i], a.b[3,i], a.b[4,i] = x
end
end
function test3()
b = Array{Int64}(undef, 4, 1000000)
a = Test_struct(b)
x = Vector{Int64}(undef, 4)
for i = 1:1000000
x = [i; 2*i; i; 2*i]
a.b[:,i] = x
end
end
function aux!(a, x, i)
a.b[1,i], a.b[2,i], a.b[3,i], a.b[4,i] = x
end
function test4()
b = Array{Int64}(undef, 4, 1000000)
a = Test_struct(b)
x = Vector{Int64}(undef, 4)
for i = 1:1000000
x = [i; 2*i; i; 2*i]
aux!(a, x, i)
end
end
println("test0")
@btime test0()
println("test1")
@btime test1()
println("test2")
@btime test2()
println("test3")
@btime test3()
println("test4")
@btime test4()
giving me the following performance information:
test0
34.999 ms (1000002 allocations: 122.07 MiB)
test1
27.547 ms (1000002 allocations: 122.07 MiB)
test2
27.495 ms (1000002 allocations: 122.07 MiB)
test3
269.969 ms (3998980 allocations: 167.83 MiB)
test4
163.860 ms (8996427 allocations: 244.09 MiB)
Which led me to the questions:
-
Why assigning values individually to an array (test1) is faster than assigning the whole column at once (test0)? (a small differente though)
-
Why when the array is inside a mutable struct, the individual assignment is 10x faster than assigning the whole column (tests2 and 3)?
-
why when i pass this struct for the assignment to happen inside another function it is much slower (test4), which doesn’t happen if i’m working with an array that is not inside a mutable struct.
-
and most importantly, from these tests it appears placing the arrays inside the structs is not the way to go. How can i group the arrays is a way to pass a single object to the function and that this problem doesn’t happen? I don’t want to just put everything inside a vector because it will be hard to deal with the different arrays without their names.
(I’m kinda new to julia, but i put this under performance because it seems to be more about performance than the very basic of the programming knowledge)
Edit: Included mutable struct definition