diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2017-02-23 14:40:00 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2017-02-23 16:56:20 -0500 |
| commit | fe1cabb88a060378c839bda53992882f67b525c7 (patch) | |
| tree | 618907c2edc5d9ec183e850eab5a958e789da042 /lib/sqlalchemy/orm | |
| parent | 4c5cfa8bc6cc5dba9a3d8f28abc01f652c0c952e (diff) | |
| download | sqlalchemy-fe1cabb88a060378c839bda53992882f67b525c7.tar.gz | |
Performance within instances()
Continuing from Ie43beecf37945b2bb7fff0aaa597a597293daa18,
also observed is the overhead of PathRegsitry memoized token
functions, as these paths are not cached in the case of
long joinedloader chains. The memoizations here were made
with short paths in mind, and have been replaced with
an inlined straight create of these paths up front, producing
callcounts very similar to 0.8. Combined with the previous
optimizations, 1.1 now runs the "joined eager load of one row"
worst case test in about 40% fewer calls than 0.8 and 60%
fewer than 1.1.5.
Change-Id: Ib5e1c1345a1dd8edfbdb3fed06eb717d4e164d31
Fixes: #3915
Diffstat (limited to 'lib/sqlalchemy/orm')
| -rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 17 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/path_registry.py | 34 |
2 files changed, 23 insertions, 28 deletions
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 3fad83ef4..fbe8f503e 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -28,6 +28,7 @@ from .base import (InspectionAttr, InspectionAttr, InspectionAttrInfo, _MappedAttribute) import collections from .. import inspect +from . import path_registry # imported later MapperExtension = SessionExtension = AttributeExtension = None @@ -459,10 +460,24 @@ class StrategizedProperty(MapperProperty): """ - __slots__ = '_strategies', 'strategy' + __slots__ = ( + '_strategies', 'strategy', + '_wildcard_token', '_default_path_loader_key' + ) strategy_wildcard_key = None + def _memoized_attr__wildcard_token(self): + return ("%s:%s" % ( + self.strategy_wildcard_key, path_registry._WILDCARD_TOKEN), ) + + def _memoized_attr__default_path_loader_key(self): + return ( + "loader", + ("%s:%s" % ( + self.strategy_wildcard_key, path_registry._DEFAULT_TOKEN), ) + ) + def _get_context_loader(self, context, path): load = None diff --git a/lib/sqlalchemy/orm/path_registry.py b/lib/sqlalchemy/orm/path_registry.py index 0377f9619..580995ab3 100644 --- a/lib/sqlalchemy/orm/path_registry.py +++ b/lib/sqlalchemy/orm/path_registry.py @@ -203,6 +203,13 @@ class PropRegistry(PathRegistry): self.parent = parent self.path = parent.path + (prop,) + self._wildcard_path_loader_key = ( + "loader", + self.parent.path + self.prop._wildcard_token + ) + self._default_path_loader_key = self.prop._default_path_loader_key + self._loader_key = ("loader", self.path) + def __str__(self): return " -> ".join( str(elem) for elem in self.path @@ -216,33 +223,6 @@ class PropRegistry(PathRegistry): def entity(self): return self.prop.mapper - @util.memoized_property - def _wildcard_path_loader_key(self): - """Given a path (mapper A, prop X), replace the prop with the wildcard, - e.g. (mapper A, 'relationship:.*') or (mapper A, 'column:.*'), then - return within the ("loader", path) structure. - - """ - return ("loader", - self.parent.token( - "%s:%s" % ( - self.prop.strategy_wildcard_key, _WILDCARD_TOKEN) - ).path - ) - - @util.memoized_property - def _default_path_loader_key(self): - return ("loader", - self.parent.token( - "%s:%s" % (self.prop.strategy_wildcard_key, - _DEFAULT_TOKEN) - ).path - ) - - @util.memoized_property - def _loader_key(self): - return ("loader", self.path) - @property def mapper(self): return self.entity |
