Opened 3 years ago
Last modified 6 weeks ago
#34521 new Cleanup/optimization
Use __slots__ for template Node classes — at Initial Version
| Reported by: | Adam Johnson | Owned by: | nobody |
|---|---|---|---|
| Component: | Template system | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Keryn Knight, Carlton Gibson | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | yes |
| Easy pickings: | no | UI/UX: | no |
Description
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 all template Node classes to save further memory. This 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:
$ 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'