-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize startup time using lazy imports #543
Conversation
Codecov Report
@@ Coverage Diff @@
## master #543 +/- ##
==========================================
- Coverage 99.48% 99.37% -0.12%
==========================================
Files 80 80
Lines 5282 5296 +14
==========================================
+ Hits 5255 5263 +8
- Misses 27 33 +6
Continue to review full report at Codecov.
|
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
I also looked at the option of implementing truly lazy imports, for example as described in the importlib standard module. But that didn't seem very appealing - it takes a nontrivial amount of code and can be hard to debug if the imports fail for some reason. So I chose to use local imports instead, which are easier to understand if not always so elegant. |
Looking at CI test results and especially Codecov, I think we need additional tests for the ImportError/ValueError clauses in |
I will try again with a less invasive approach that doesn't try to avoid importing NumPy. It's not worth complicating the code with many local imports just to speed up the startup by less than 0.1 seconds. |
Fixes #514
The goal of this PR is to reduce CLI startup time by avoiding useless work, especially imports that are not necessary for the requested operation.
It makes the following changes to the import statements within the Annif codebase:
annif/backend/__init__.py
; the end result is that backends (and the libraries they require, e.g. fasttext, omikuji and tensorflow) are only imported when they are actually usedI tried to craft the changes to have minimal impact on the code so I only chose to make imports local in cases where there were very few uses within the same module. For example
annif.suggestion
uses NumPy a lot, so I didn't try to use local imports within that module, but instead avoided importing the wholeannif.suggestion
module in other parts of the codebase.Startup time for simple commands such as
annif --help
andannif --version
has been reduced by more than two thirds.Before:
After:
As explained in #514, I also used tuna to visualize where the remaining import time is spent after this PR:
The main culprits are now
connexion
(with most of the time spent initializingopenapi_spec_validator
!) andflask
. Those are core libraries and I don't think we can avoid importing them even for the simplest CLI commands.