feat: add lazy imports for faster startup time #160
+83
−38
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
For easier review, this is broken out feature I wrote in #150
This uses lazy imports
Issue Being Solved
The problem is that the startup time of the
yolo/lazy.py
script is very long becauseyolo/__init__.py
explicitly imports a lot of heavyweight dependencies.Previously running:
time python -m yolo.lazy --help
took 3 seconds on my machine. After this patch it now takes 0.3 seconds, a 10x improvement.It works using the lazy-loader module. Instead of explicitly importing everything, it only will import them if they are used. You can also specify the
EAGER_IMPORT=1
environment variable to have it import everything on startup as it used to. E.g, the following command will revert to the old 3 second startup time:time EAGER_IMPORT=True python -m yolo.lazy --help
Additionally I had to move a few imports in
lazy.py
itself into the main function so it can hit the hydra code before it starts to import all of lightning.Note on mkinit
Note, that I wrote this using mkinit autogeneration, which is why there is a
__submodules__
and__autogen__
definition at the top. Technically this can be removed. But it also lets you regenerate the__init__.py
file more easily if anything changes. It can even reconstruct the original explicit definition of the file with:On Dependencies
This does add a dependency on lazy-loader, but that could be removed by defining the
lazy_loader.attach
directly in the__init__.py
, but it is a bit ugly, so I tend to prefer using the lightweight package. Runningmkinit
with--lazy
instead of--lazy-loader
will generate this variant of the code.