When I am working with scientific projects, I am quite an old school guy who writes code and executes that with include("source.jl") in the Julia REPL. That had worked pretty well so far, but today I encountered a recompilation issue which makes my work less pleasant. A code which I execute with Julia 1.3 is:
using DifferentialEquations
struct PS{T}
V::T
VR::T
r::T
C::T
Vext::Function
end
function phaseslip!(dq,q,p,t)
V,VR,r,C,Vext = p.V, p.VR, p.r, p.C, p.Vext
qL,qR = q[1],q[2]
dq[1] = V - sin(qL) - 1/C * (qL - qR) - Vext(t)
dq[2] = - VR * sin(qR) + r/C * (qL - qR) + r*Vext(t)
end
### Solving the system
p = PS(0.5,0.5,0.5,2.0,t->0.1*sin(t))
q0 = [0.,0.]
tspan = (0.0,2000)
prob = ODEProblem(phaseslip!,q0,tspan,p)
@time sol = solve(prob,dtmax=1.)
Every time I run it, I get 2.6 seconds. If I specifically execute the part after “Solving the system” I get 0.01 second. What is the reason for such behaviour? How can I avoid that?
The solution for me would be something within the lines of the following code:
function interactiveinclude(fname,h)
hnew = hash(readlines(fname))
if hnew!=h
@eval include($fname)
end
return hnew
end
#include("formulation.jl")
function interactiveinclude(fname)
@eval begin
isdefined(Main,:h) || (h = nothing)
h = interactiveinclude($fname,h)
end
end
interactiveinclude("formulation.jl")
A dirty fix but works as expected. Does anyone already have a package for that?
Yes, and it does that job quite well. I always use it when I develop packages. However, I am not sure if I do want to structure my research code as a package. Part of the reason being that I am still trying to sell Julia to my supervisor, who just figured out that it is a great idea to enforce Python on the group because everyone uses it. Commonality I think could help a lot.
BTW I really think that over-definition of a method should never happen if an exact definition of method or a type is already loaded.
Note that if the problem is recompilation of methods that are actually being edited rather than package loading or recompilation of unchanged methods, first use after redefinition will still be slow.
Yes, you definitely want to do that. The main advantage is being able to commit the Manifest.toml to your version control repository, resulting an perfectly reproducible environment (as far as dependencies are concerned).
Once you start relying on it, this is one of those “how did I live without this?” features.
You should still be able to interface with code from others using one of the Python interop packages:
I changed structure of my code to the one of the package. Indeed I am thinking why I did not do that earlier It also fixed the issue of the recompilation as using MyModule always runs quick.