# @code_warntype ODEProblem shows `Any`

I tried the example here and see what `@code_warntype` returns:

``````julia> using DifferentialEquations

julia> function lorenz(du,u,p,t)
du[1] = 10.0*(u[2]-u[1])
du[2] = u[1]*(28.0-u[3]) - u[2]
du[3] = u[1]*u[2] - (8/3)*u[3]
end
lorenz (generic function with 1 method)

julia> u0 = [1.0;0.0;0.0]
3-element Array{Float64,1}:
1.0
0.0
0.0

julia> tspan = (0.0,100.0)
(0.0, 100.0)

julia> @code_warntype ODEProblem(lorenz,u0,tspan)
Variables:
#self#::Type{DiffEqBase.ODEProblem}
f::#lorenz
u0::Array{Float64,1}
tspan::Tuple{Float64,Float64}

Body:
begin
return \$(Expr(:invoke, MethodInstance for #ODEProblem#185(::Array{Any,1}, ::Type{T} where T, ::Function, ::Array{Float64,1}, ::Tuple{Float64,Float64}, ::Void), :(DiffEqBase.#ODEProblem#185), :(\$(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Any,1}, svec(Any, Int64), Array{Any,1}, 0, 0, 0))), :(#self#), :(f), :(u0), :(tspan), :(DiffEqBase.nothing)))
end::Any
``````

Under what circumstances will it return a type other than `DiffEqBase.ODEProblem`? If I embed it into some simulation code, it will return `Any`, would that affect performance?

Solving any ODE takes so much longer than the 10-100ns of a single dynamic dispatch that `solve` acts as a good function barrier here. I would be heavily surprised if that caused a performance difference anywhere (and if it did, just `let` block it)

Just so that the details are out there, the issue stems from the keyword argument use which gets added via the macro

so that the `remake` function can utilize a keyword argument version of the constructor. However, Julia doesnâ€™t optimize keyword arguments at all on v0.6 so that is where the lack of inference comes from. Additionally, there is one parameter which isnâ€™t ever inferred which is `isinplace`, but you can just declare that your function is in place like `ODEProblem{true}(lorenz,u0,tspan)`. If you took off the macro, this will be inferred, but the in-place checking + keyword argument handling is what causes the issue.

But again, if all youâ€™re doing with it is calling `solve` on the ODE then thereâ€™s no performance hit. Though you do need to make sure you shield downstream usage because keyword argument problems mean that the solution isnâ€™t inferred. In the vast majority of cases though, analyzing the solutionâ€™s return isnâ€™t where the time is really spent so youâ€™re fine, but if it happens to be, then just put a function barrier or a `let` block there. But this is all set to fix itself once kwargs specialize enough (and I think Julia v0.7 has â€śenoughâ€ť?)

1 Like