Opened 20 months ago

Last modified 19 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 Adam Johnson)

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'

Change History (1)

comment:1 by Adam Johnson, 20 months ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top