mirror of
https://github.com/django/django.git
synced 2025-06-05 11:39:13 +00:00
Refs #35102 -- Optimized Expression.identity used for equality and hashing.
inspect.signature() is quite slow and produces the same object for each instance of the same class as they share their __init__ method which makes it a prime candidate for caching. Thanks Anthony Shaw for the report.
This commit is contained in:
parent
92d6cff6a2
commit
d074c7530b
@ -14,7 +14,7 @@ from django.db.models import fields
|
|||||||
from django.db.models.constants import LOOKUP_SEP
|
from django.db.models.constants import LOOKUP_SEP
|
||||||
from django.db.models.query_utils import Q
|
from django.db.models.query_utils import Q
|
||||||
from django.utils.deconstruct import deconstructible
|
from django.utils.deconstruct import deconstructible
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property, classproperty
|
||||||
from django.utils.hashable import make_hashable
|
from django.utils.hashable import make_hashable
|
||||||
|
|
||||||
|
|
||||||
@ -485,13 +485,18 @@ class BaseExpression:
|
|||||||
class Expression(BaseExpression, Combinable):
|
class Expression(BaseExpression, Combinable):
|
||||||
"""An expression that can be combined with other expressions."""
|
"""An expression that can be combined with other expressions."""
|
||||||
|
|
||||||
|
@classproperty
|
||||||
|
@functools.lru_cache(maxsize=128)
|
||||||
|
def _constructor_signature(cls):
|
||||||
|
return inspect.signature(cls.__init__)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def identity(self):
|
def identity(self):
|
||||||
constructor_signature = inspect.signature(self.__init__)
|
|
||||||
args, kwargs = self._constructor_args
|
args, kwargs = self._constructor_args
|
||||||
signature = constructor_signature.bind_partial(*args, **kwargs)
|
signature = self._constructor_signature.bind_partial(self, *args, **kwargs)
|
||||||
signature.apply_defaults()
|
signature.apply_defaults()
|
||||||
arguments = signature.arguments.items()
|
arguments = iter(signature.arguments.items())
|
||||||
|
next(arguments)
|
||||||
identity = [self.__class__]
|
identity = [self.__class__]
|
||||||
for arg, value in arguments:
|
for arg, value in arguments:
|
||||||
if isinstance(value, fields.Field):
|
if isinstance(value, fields.Field):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user