#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 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'
> }}}

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 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'
 }}}

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34521#comment:1>
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/01070187c1768d9e-aa046499-fee0-4e8c-a74b-d7fc80bd43f4-000000%40eu-central-1.amazonses.com.

Reply via email to