feat: add lazy imports for faster startup time #160
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.pyscript is very long becauseyolo/__init__.pyexplicitly imports a lot of heavyweight dependencies.Previously running:
time python -m yolo.lazy --helptook 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=1environment 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 --helpAdditionally I had to move a few imports in
lazy.pyitself 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__.pyfile 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.attachdirectly in the__init__.py, but it is a bit ugly, so I tend to prefer using the lightweight package. Runningmkinitwith--lazyinstead of--lazy-loaderwill generate this variant of the code.