#34521: Use __slots__ for template Node classes
-------------------------------------+-------------------------------------
Reporter: Adam Johnson | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Template system | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Adam Johnson:
Old 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 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'
> }}}
New 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 more template classes to further save memory
(Template, Token, Lexer, and the Node classes). This change leads to 1-2%
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 ticket_34521_optimize_templates' \
'python benchmark.py'
Benchmark 1: python benchmark.py
Time (mean ± σ): 2.028 s ± 0.042 s [User: 1.990 s, System:
0.035 s]
Range (min … max): 1.997 s … 2.116 s 10 runs
Benchmark 2: python benchmark.py
Time (mean ± σ): 1.985 s ± 0.007 s [User: 1.950 s, System:
0.033 s]
Range (min … max): 1.976 s … 1.997 s 10 runs
Summary
'python benchmark.py' ran
1.02 ± 0.02 times faster than 'python benchmark.py'
}}}
(I decided not to use djangobench since it's not well maintained, and
doesn't do such great stats as hyperfine.)
--
--
Ticket URL: <https://code.djangoproject.com/ticket/34521#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/01070187c18175a5-7d8a9b68-b19e-4ba1-bfb1-127b0ad5ed12-000000%40eu-central-1.amazonses.com.