[Django] #35241: Cache Model._meta.get_parent_list()

20 views
Skip to first unread message

Django

unread,
Feb 20, 2024, 5:40:23 PM2/20/24
to django-...@googlegroups.com
#35241: Cache Model._meta.get_parent_list()
-------------------------------------+-------------------------------------
Reporter: Adam | Owner: Adam Johnson
Johnson |
Type: | Status: assigned
Cleanup/optimization |
Component: Database | Version: dev
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 1
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Another candidate for caching, like #35230 and #35232, following the same
system check profiling.

`Model._meta.get_parent_list()` computes the flattened list of ancestor
models by MRO. This list is immutable, deterministic, and recursively
constructed through the inheritance hierarchy. These properties make it a
prime candidate for caching.

I found this method was taking ~1% of the total runtime for system checks
on a project with 118 models. After adding caching, it’s reduced to a
negligible amount.

`get_parent_list()` is called in many other code paths, so caching will
help all of those too.
--
Ticket URL: <https://code.djangoproject.com/ticket/35241>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 22, 2024, 7:13:22 AM2/22/24
to django-...@googlegroups.com
#35241: Cache Model._meta.get_parent_list()
-------------------------------------+-------------------------------------
Reporter: Adam Johnson | Owner: Adam
Type: | Johnson
Cleanup/optimization | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):

* stage: Unreviewed => Accepted

Comment:

Thank you Adam! Do you have concrete benchmark numbers to share?
--
Ticket URL: <https://code.djangoproject.com/ticket/35241#comment:1>

Django

unread,
Feb 22, 2024, 12:57:10 PM2/22/24
to django-...@googlegroups.com
#35241: Cache Model._meta.get_parent_list()
-------------------------------------+-------------------------------------
Reporter: Adam Johnson | Owner: Adam
Type: | Johnson
Cleanup/optimization | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):

* needs_better_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/35241#comment:2>

Django

unread,
Feb 22, 2024, 4:15:23 PM2/22/24
to django-...@googlegroups.com
#35241: Cache Model._meta.get_parent_list()
-------------------------------------+-------------------------------------
Reporter: Adam Johnson | Owner: Adam
Type: | Johnson
Cleanup/optimization | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Old description:

> Another candidate for caching, like #35230 and #35232, following the same
> system check profiling.
>
> `Model._meta.get_parent_list()` computes the flattened list of ancestor
> models by MRO. This list is immutable, deterministic, and recursively
> constructed through the inheritance hierarchy. These properties make it a
> prime candidate for caching.
>
> I found this method was taking ~1% of the total runtime for system checks
> on a project with 118 models. After adding caching, it’s reduced to a
> negligible amount.
>
> `get_parent_list()` is called in many other code paths, so caching will
> help all of those too.

New description:

Another candidate for caching, like #35230 and #35232, following the same
system check profiling.

`Model._meta.get_parent_list()` computes the flattened list of ancestor
models by MRO. This list is immutable, deterministic, and recursively
constructed through the inheritance hierarchy. These properties make it a
prime candidate for caching.

I found this method was taking ~1% (0.39ms) of the total runtime for
system checks on a project with 118 models. After adding caching, it’s
reduced to a negligible amount (<0.01ms).

`get_parent_list()` is called in many other code paths, so caching will
help all of those too.

--
Comment (by Adam Johnson):

I added concrete numbers to the description.
--
Ticket URL: <https://code.djangoproject.com/ticket/35241#comment:3>

Django

unread,
Feb 22, 2024, 6:07:49 PM2/22/24
to django-...@googlegroups.com
#35241: Cache Model._meta.get_parent_list()
-------------------------------------+-------------------------------------
Reporter: Adam Johnson | Owner: Adam
Type: | Johnson
Cleanup/optimization | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Adam Johnson):

* needs_better_patch: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/35241#comment:4>

Django

unread,
Feb 23, 2024, 1:40:43 PM2/23/24
to django-...@googlegroups.com
#35241: Cache Model._meta.get_parent_list()
-------------------------------------+-------------------------------------
Reporter: Adam Johnson | Owner: Adam
Type: | Johnson
Cleanup/optimization | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):

* needs_better_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/35241#comment:5>

Django

unread,
Feb 24, 2024, 6:08:25 PM2/24/24
to django-...@googlegroups.com
#35241: Cache Model._meta.get_parent_list()
-------------------------------------+-------------------------------------
Reporter: Adam Johnson | Owner: Adam
Type: | Johnson
Cleanup/optimization | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Adam Johnson):

* needs_better_patch: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/35241#comment:6>

Django

unread,
Feb 25, 2024, 11:48:36 PM2/25/24
to django-...@googlegroups.com
#35241: Cache Model._meta.get_parent_list()
-------------------------------------+-------------------------------------
Reporter: Adam Johnson | Owner: Adam
Type: | Johnson
Cleanup/optimization | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/35241#comment:7>

Django

unread,
Feb 26, 2024, 12:12:44 AM2/26/24
to django-...@googlegroups.com
#35241: Cache Model._meta.get_parent_list()
-------------------------------------+-------------------------------------
Reporter: Adam Johnson | Owner: Adam
Type: | Johnson
Cleanup/optimization | Status: closed
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

* resolution: => fixed
* status: assigned => closed

Comment:

In [changeset:"73d5eb808435bcf27ebc935847196ac9e97b6ddc" 73d5eb8]:
{{{#!CommitTicketReference repository=""
revision="73d5eb808435bcf27ebc935847196ac9e97b6ddc"
Fixed #35241 -- Cached model's full parent list.

co-authored-by: Keryn Knight <ke...@kerynknight.com>
co-authored-by: Natalia <124304+...@users.noreply.github.com>
co-authored-by: David Smith <smi...@gmail.com>
co-authored-by: Paolo Melchiorre <pa...@melchiorre.org>
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/35241#comment:8>
Reply all
Reply to author
Forward
0 new messages