I have a function which I need to make as efficient as possible.
The function takes many many inputs, and I have organised them into a structure in order to make the code more manageble and clean.
I have noticed that some times when within the function I modify the content of the structure pass to the function then some memory allocation happens, which slows down the code.
Here is a working example. Is there a way to avoid allocation while keep using a structure, or something similar, to group the inputs?
Thank you
Best
Francesco
using BenchmarkTools
mutable struct My_struct
vector_1::AbstractVector
end
function my_function!(input::My_struct)
input.vector_1[1] = 1 + input.vector_1[2] # allocations occur here, I guess to manage the right hand side
return nothing
end
# test
structure_1 = My_struct(ones(10))
@btime my_function!(structure_1)
I don’t know exactly where the allocations come from, but you are using two performance anti-patterns and removing those solves this in my testing.
First of all, in your code example, and also more generally in the situation you describe, there is no reason for the struct to be mutable. You seem to confuse mutable with const-ness from other languages. In Julia, you can absolutely modify the contents of vector_1 even if the struct is not mutable.
Secondly, you shouldn’t have abstract types like AbstractVector in your fields. It’s much better to parametrize.
Solving these two issues gives:
julia> struct My_struct_2{V}
vector_1::V
end
julia> function my_function!(input::My_struct_2)
input.vector_1[1] = 1 + input.vector_1[2] # allocations occur here, I guess to manage the right hand side
return nothing
end
my_function! (generic function with 2 methods)
julia> # test
structure_2 = My_struct_2(ones(10))
My_struct_2{Array{Float64,1}}([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
julia> @btime my_function!(structure_2)
11.556 ns (0 allocations: 0 bytes)
Do read the performance tips – it clearly describes this latter issue.