Opened 19 months ago
Last modified 18 months ago
#34521 closed Cleanup/optimization
Use __slots__ for template Node classes — at Version 1
Reported by: | Adam Johnson | Owned by: | nobody |
---|---|---|---|
Component: | Template system | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Keryn Knight, Carlton Gibson | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Declaring slots reduces the memory footprint of a class, and can lead to performance gains due to less data fetching by the CPU.
#12826 proposed adding slots to many classes but was closed with the proposal to do so on a case-by-case basis.
#33474 added slots to Variable
and related classes, showing memory reductions and performance gains.
I propose adding slots to more template classes to further save memory (Template, Token, Lexer, and the Node classes). This change leads to about a 1% improvement in template rendering time, using this benchmark script:
import django from django.conf import settings from django.template import Context from django.template import Template settings.configure( TEMPLATES=[{"BACKEND": "django.template.backends.django.DjangoTemplates"}] ) django.setup() template = Template("{% if x %}{{ x }}{% endif %}" * 1_000) context = Context({"x": "abc"}) for i in range(1_000): template.render(context)
And invoking [hyperfine](https://github.com/sharkdp/hyperfine) like so, with Python 3.11.2:
$ hyperfine \ -N --warmup 1 \ --prepare 'git switch -d 7d0e566208' \ 'python benchmark.py' \ --prepare 'git switch optimize_templates' \ 'python benchmark.py' Benchmark 1: python benchmark.py Time (mean ± σ): 2.006 s ± 0.007 s [User: 1.968 s, System: 0.035 s] Range (min … max): 1.995 s … 2.013 s 10 runs Benchmark 2: python benchmark.py Time (mean ± σ): 1.993 s ± 0.008 s [User: 1.958 s, System: 0.034 s] Range (min … max): 1.984 s … 2.012 s 10 runs Summary 'python benchmark.py' ran 1.01 ± 0.01 times faster than 'python benchmark.py'