Hello,
I’m a very basic Julia user working on a model simulating a food web and fishing. The model works but I need to decrease the run time. I’ve read several tutorials about @code_warntype
and I understand I should define types where possible, to not change them within a function, and to not mix types.
However, the MWEs do not answer my questions. I understand they are supposed to be minimal. I have tried creating a MWE, but I am not so skilled. I have some nested functions.
This is how I understand the output of @code_warntype
- please correct me if I am wrong. My function is called generating_pristine
.
MethodInstance - this first states the type of parameters, and then the name of the parameters used in a function
Arguments - these are the named parameters together with their type (coloured) used in the function
The first line is #self#::Core.Const(generating_pristine)
- what does this mean?
index_vessel@_11::Int64
index_clearance@_12::Int64
index_extinction_parameter::Int64
index_callback_pristine::Vector{Float64}
What does @_11
or @_12
mean? Why are not all parameters given a number?
Locals - I think these are objects within the function, that include the named parameters
@_22::Union{Nothing, Tuple{Tuple{Int64, Any}, Tuple{Int64, Any}}}
#49::var"#49#52"
@_24::Int64
file_name_pristine::String
Why are some objects numbered? Do they refer to the code line or object compiled? Or the nth time a parameter is called?
Body - I think this is where the calculations get done
%94 = Base.indexed_iterate(%36, 20, @_24::Core.Const(20))::Core.PartialStruct(Tuple{Any, Int64}, Any[Any, Core.Const(21)])
(trophic_position = Core.getfield(%94, 1))
(@_24 = Core.getfield(%94, 2))
%97 = Base.indexed_iterate(%36, 21, @_24::Core.Const(21))::Core.PartialStruct(Tuple{Any, Int64}, Any[Any, Core.Const(22)])
%98 = Core.getfield(%97, 1)::Any
Core.setfield!(num_nutrient@_94::Core.Box, :contents, %98)
(@_24 = Core.getfield(%97, 2))
Is %94
like the 94th time step while running the function? I know I need to focus on the ::Any
, but I don’t understand what part of the code or to what parameter/object it is referring to.
I have a lot of ::Any
, but I don’t understand why as I have set the type for index_vessel
earlier, shown by index_vessel@_11::Int64
in the Arguments.
%198 = Core.getfield(index_vessel@_100::Core.Box, :contents)::Any
│ %199 = (%198 - 1)::Any
│ %200 = (%192:%199)::Any
│ %201 = Base.getindex(%185, %200)::Any
│ %202 = Base.broadcasted(Main.:<=, %201, 0.0)::Any
│ %203 = Base.materialize(%202)::Any
│ %204 = Main.sum(%203)::Any
│ %205 = Base.convert(Main.Int64, %204)::Any
│ (extinct_pristine = Core.typeassert(%205, Main.Int64))
│ %207 = extinct_pristine::Int64
│ %208 = Core.isdefined(num_nutrient@_94::Core.Box, :contents)::Bool
I thought if you define a parameter, and pass it into a function, it should keep the same data and type.
I’m feeling quite lost in this. Any help is appreciated.
These are the references I have used
https://docs.julialang.org/en/v1/manual/performance-tips/
https://tutorials.sciml.ai/html/introduction/03-optimizing_diffeq_code.html
https://techytok.com/code-optimisation-in-julia/
https://book.sciml.ai/notes/02/
https://www.cs.purdue.edu/homes/hnassar/JPUG/performance.html
https://m3g.github.io/JuliaNotes.jl/stable/instability/