Opened 9 months ago
Last modified 8 months ago
#35270 closed Cleanup/optimization
Optimize Model._meta._property_names — at Version 1
Reported by: | Adam Johnson | Owned by: | Adam Johnson |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Keryn Knight | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Continuing my project to optimize the system checks, I found some optimizations for Options._meta._property_names
, which I found to take ~4% of the total runtime for checks.
Most of this function’s runtime was being spent running inspect.getattr_static()
. This is not surprising as it jumps through many hoops in order to avoid triggering attribute access.
I added use of getattr_static()
back in #28269 / ed244199c72f5bbf33ab4547e06e69873d7271d0 to fix a bug with instance descriptors. But I think it’s overly cautious, and we can assume that accessing the __dict__
of the model class will work fine.
Two optimizations make the function run in negligible time:
- Changing the function to use
__dict__
directly - Caching on a per-class basis. This requires using a weak-reference to classes, as we shouldn’t mutate base classes in the MRO, some of which can be non-model subclasses, like
Model
itself for thepk
property,object
, or any mixins.
Before optimization stats:
106 calls to _property_names
took 26ms, or ~4% of the total runtime of system checks.
After optimization:
The same calls take 1ms, or ~0.2% of the total runtime. (The real runtime may be <1ms, but shows as 1 due to rounding up by cProfile.)