From 402677f687ecdb78026864188bae50b9d85949de Mon Sep 17 00:00:00 2001 From: James Westman Date: Mon, 20 Mar 2023 13:34:17 -0500 Subject: [PATCH] performance: Cache some properties --- blueprintcompiler/ast_utils.py | 19 +++++++++++-------- blueprintcompiler/language/ui.py | 3 ++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/blueprintcompiler/ast_utils.py b/blueprintcompiler/ast_utils.py index 7bd5418..73ffe62 100644 --- a/blueprintcompiler/ast_utils.py +++ b/blueprintcompiler/ast_utils.py @@ -76,6 +76,7 @@ class AstNode: """Base class for nodes in the abstract syntax tree.""" completers: T.List = [] + attrs_by_type: T.Dict[T.Type, T.List] = {} def __init__(self, group, children, tokens, incomplete=False): self.group = group @@ -92,12 +93,13 @@ class AstNode: cls.validators = [ getattr(cls, f) for f in dir(cls) if hasattr(getattr(cls, f), "_validator") ] + cls.attrs_by_type = {} @cached_property def context(self): return Ctx(self) - @property + @cached_property def root(self): if self.parent is None: return self @@ -140,13 +142,14 @@ class AstNode: for child in self.children: yield from child._get_errors() - def _attrs_by_type( - self, attr_type: T.Type[TAttr] - ) -> T.Iterator[T.Tuple[str, TAttr]]: - for name in dir(type(self)): - item = getattr(type(self), name) - if isinstance(item, attr_type): - yield name, item + def _attrs_by_type(self, attr_type: T.Type[TAttr]) -> T.List[T.Tuple[str, TAttr]]: + if attr_type not in self.attrs_by_type: + self.attrs_by_type[attr_type] = [] + for name in dir(type(self)): + item = getattr(type(self), name) + if isinstance(item, attr_type): + self.attrs_by_type[attr_type].append((name, item)) + return self.attrs_by_type[attr_type] def get_docs(self, idx: int) -> T.Optional[str]: for name, attr in self._attrs_by_type(Docs): diff --git a/blueprintcompiler/language/ui.py b/blueprintcompiler/language/ui.py index d45fe4c..aeff186 100644 --- a/blueprintcompiler/language/ui.py +++ b/blueprintcompiler/language/ui.py @@ -17,6 +17,7 @@ # # SPDX-License-Identifier: LGPL-3.0-or-later +from functools import cached_property from .. import gir from .imports import GtkDirective, Import @@ -82,7 +83,7 @@ class UI(AstNode): or isinstance(child, Menu) ] - @property + @cached_property def objects_by_id(self): return { obj.tokens["id"]: obj