Skip to content

Commit

Permalink
Performance: add cached_property for common schema field accesses
Browse files Browse the repository at this point in the history
Fields like 'auth' can be accessed more than 800 times per request.
Replacing this with a cached property speeds up access a lot.
Also note that most fields don't have an auth, which caused a call to
__missing__() for every field too.
  • Loading branch information
vdboor committed Jul 8, 2024
1 parent 6576c7b commit c424a7d
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/schematools/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ def __deepcopy__(self, memo):
def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.data!r})"

def __setitem__(self, key, value):
if key in self.data and key in self.__dict__:
# Clear the @cached_property cache value
del self.__dict__[key]
super().__setitem__(key, value)

if IS_DEBUGGER:

def __missing__(self, key: str) -> NoReturn:
Expand Down Expand Up @@ -373,7 +379,7 @@ def is_default_version(self) -> bool:
Defaults to True, in order to stay backwards compatible."""
return self.default_version == self.version

@property
@cached_property
def auth(self) -> frozenset[str]:
"""Auth of the dataset, or OPENBAAR."""
return _normalize_scopes(self.get("auth"))
Expand Down Expand Up @@ -759,7 +765,7 @@ def __init__(
def __repr__(self):
return f"<{self.__class__.__name__}: {self.qualified_id}>"

@property
@cached_property
def qualified_id(self) -> str:
"""The fully qualified ID (for debugging)"""
prefix = ""
Expand Down Expand Up @@ -1084,7 +1090,7 @@ def get_reverse_relation(self, field: DatasetFieldSchema) -> AdditionalRelationS

return None

@property
@cached_property
def auth(self) -> frozenset[str]:
"""Auth of the table, or OPENBAAR."""
return _normalize_scopes(self.get("auth"))
Expand Down Expand Up @@ -1298,7 +1304,7 @@ def parent_field(self) -> DatasetFieldSchema | None:
"""Provide access to the top-level field where it is a property for."""
return self._parent_field

@property
@cached_property
def qualified_id(self) -> str:
"""The fully qualified ID (for debugging)"""
prefix = ""
Expand Down Expand Up @@ -1759,13 +1765,15 @@ def is_relation_temporal(self):
self.is_composite_key or self.related_table.is_temporal
)

@property
@cached_property
def auth(self) -> frozenset[str]:
"""Auth of the field, or OPENBAAR.
When the field is a subfield, the auth has been defined on
the parent field, so we need to return the auth of the parent field.
"""
# As this call is made so many times, this is a cached_property
# to avoid hitting __missing__() too many times.
if self.is_subfield:
return self.parent_field.auth
return _normalize_scopes(self.get("auth"))
Expand Down Expand Up @@ -2016,7 +2024,7 @@ def name(self) -> str | None:
"""Name of Profile (if set)"""
return self.get("name")

@property
@cached_property
def scopes(self) -> frozenset[str]:
"""All these scopes should match in order to activate the profile."""
return _normalize_scopes(self.get("scopes"))
Expand Down

0 comments on commit c424a7d

Please sign in to comment.