I’m building a package for which I want to minimize
using load time. It has a bunch of dependencies that are only needed for some specific functionalities, called via specific methods. Can I somehow delay loading the dependencies until the user calls the methods that use them? What is the recommended approach to such a problem?
Note: as I understand it, this is kind of the conjugate of the problem that Requires.jl solves (defining some methods only after the user loads a package).
You can put using in a function like this:
@eval using Dependency
But this works only if you call this function from global scope, if you call it inside another function, you will not get this dependency in the calling function due to world age.
Put those methods in different packages with the relevant dependencies. But not that it may not save a lot of load time in any case.
Also, is load time a bottleneck for you on 1.5/master? For most people, compilation time is more significant.
You can use
@eval Base.__toplevel__ import $pkg for loading and
Base.invokelatest(<function>, <args>) for actual using. This is how it is done in
UrlDownload.jl: https://github.com/Arkoniak/UrlDownload.jl/blob/master/src/UrlDownload.jl#L117-L138 and this implementation was taken from FileIO.jl
I am not sure, but I think that
invokelatest can be rather slow compared to a normal function call.
Hey Tamas, yes, I’m usually developing on 1.5 and the package is already at 2 sec load time, and growing. I just tried on master and… 0.7 sec. What!!?
I guess I shouldn’t worry so much about dependencies going forward
The reduction in the load time you observed in master may be an effect of the work being done to reduce invalidations.
Yeah, I know, I’ve been following that closely with much interest. It’s amazing. I just never thought to measure its effect on my work