Lazy-load zoneinfo to improve startup time#156
Open
angusholder wants to merge 3 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Motivation
In Django, ORM model classes are instantiated immediately at startup, so any heavy operations in their init path slow down your manage.py CLI startup time. Currently, instantiating a
TimeZoneFieldindirectly callszoneinfo.available_timezones()twice (via ZoneInfoBackend), which performs a lot of IO and parsing. On my machines this adds 25-35ms to startup time. Not huge on its own, but Django startup times can easily build up with a few libraries being a little bit slow. I measured this with the following script:Timing on Heztner CCX53
Timing on Apple M4 Pro
Solution
I fixed this by making the zoneinfo reads happen lazily. This required changing TimeZoneField's
choicesfield to be a lazy object itself, which unfortunately did make the code a bit more complex.I only touched the ZoneInfoBackend, and left PYTZBackend alone because I don't think even has this issue - a cursory look at its source shows it lists timezones directly in the Python file, so isn't performing IO.