#30498: lazy() class preparation is not being cached correctly
------------------------------------------------+------------------------
Reporter: Ran Benita | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Utilities | Version: master
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------------+------------------------
Doing `self.__prepared = True` changes the instance, but the intention is
to change the class variable:
https://github.com/django/django/blob/888fdf182e164fa4b24aa82fa833c90a2b9bee7a/django/utils/functional.py#L82
This makes functions like gettext_lazy, format_lazy and reverse_lazy a lot
slower than they ought to be.
Regressed in Django 1.8 (b4e76f30d12bfa8a53cc297c60055c6f4629cc4c).
Using this micro-benchmark on Python 3.7:
{{{#!python
import cProfile
from django.utils.functional import lazy
def identity(x): return x
lazy_identity = lazy(identity, int)
cProfile.run("for i in range(10000): str(lazy_identity(1))")
}}}
Before:
{{{
910049 function calls in 0.208 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.010 0.010 0.208 0.208 <string>:1(<module>)
10000 0.001 0.000 0.001 0.000 bench.py:4(identity)
10000 0.005 0.000 0.010 0.000 functional.py:105(__str__)
10000 0.004 0.000 0.188 0.000
functional.py:159(__wrapper__)
10000 0.007 0.000 0.185 0.000 functional.py:76(__init__)
10000 0.089 0.000 0.178 0.000
functional.py:83(__prepare_class__)
10000 0.004 0.000 0.005 0.000 functional.py:99(__cast)
1 0.000 0.000 0.208 0.208 {built-in method
builtins.exec}
840000 0.087 0.000 0.087 0.000 {built-in method
builtins.hasattr}
46 0.000 0.000 0.000 0.000 {built-in method
builtins.setattr}
1 0.000 0.000 0.000 0.000 {method 'disable' of
'_lsprof.Profiler' objects}
10000 0.002 0.000 0.002 0.000 {method 'mro' of 'type'
objects}
}}}
After:
{{{
50135 function calls in 0.025 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.008 0.008 0.025 0.025 <string>:1(<module>)
10000 0.001 0.000 0.001 0.000 bench.py:4(identity)
10000 0.005 0.000 0.009 0.000 functional.py:105(__str__)
10000 0.003 0.000 0.008 0.000
functional.py:159(__wrapper__)
10000 0.005 0.000 0.005 0.000 functional.py:76(__init__)
1 0.000 0.000 0.000 0.000
functional.py:83(__prepare_class__)
10000 0.004 0.000 0.005 0.000 functional.py:99(__cast)
1 0.000 0.000 0.025 0.025 {built-in method
builtins.exec}
84 0.000 0.000 0.000 0.000 {built-in method
builtins.hasattr}
46 0.000 0.000 0.000 0.000 {built-in method
builtins.setattr}
1 0.000 0.000 0.000 0.000 {method 'disable' of
'_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {method 'mro' of 'type'
objects}
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/30498>
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 post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/051.368e1524f97fe0a4028c8d3f3d70be7e%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.