Skip to content

Conversation

adamchainz
Copy link
Member

@adamchainz adamchainz commented Oct 3, 2024

Trac ticket number

ticket-34521

Branch description

Following this forum discussion, this PR is a repeat of #16805, but limited to just Node classes and NodeList, to deal with compatibility concerns. According to my benchmark, this change saves about 20% of the memory for templates and speeds up rendering by up to 6%.

Because attributes named in __slots__ cannot be class attributes, Node.token and NodeList.contains_nontext have been converted to instance attributes, defined in __init__(). This change requires that all their subclasses call super().__init__(), which was not the case previously.

Checklist

  • This PR targets the main branch.
  • The commit message is written in past tense, mentions the ticket number, and ends with a period.
  • I have checked the "Has patch" ticket flag in the Trac system.
  • I have added or updated relevant tests.
  • I have added or updated relevant docs, including release notes if applicable.
  • I have attached screenshots in both light and dark modes for any UI changes.

Template parsing instantiates one lexer per template and many tokens per
template, so using __slots__ to reduce the memory footprint of these classes is
worthwhile for performance.
Parsed templates may contain many NodeList instances, so using __slots__ to
reduce the memory footprint of these classes is worthwhile for performance.
@adamchainz adamchainz marked this pull request as ready for review September 6, 2025 22:04
@adamchainz
Copy link
Member Author

I've just pushed new version with the change split into three commits, addressing @kezabelle 's review.

@adamchainz adamchainz changed the title Refs #34521 -- Added __slots__ to template Node classes. Fixed #34521 -- Added __slots__ to several template classes. Sep 6, 2025
Templates can contain many nodes, so using __slots__ to reduce the memory
footprint of Node classes is worthwhile for performance.

Attributes named in `__slots__` cannot be set at the class level, so this has
needed an adjustment to `Node` to make `token` and `origin` instance attributes
instead of class attributes. `Node` classes in Django and many packages do not
call `super().__init__()` in their `__init__()` methods, because they have
never had to, so `Node.__new__()` has been overridden to set these attributes
for new instances instead of using `Node.__init__()`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants