You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by gi...@apache.org on 2020/12/29 13:06:28 UTC

[buildstream] 01/05: element.py: Extract __expand_splits to a cython module

This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch bschubert/optimize-element-init
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit efd9d179916540c1aa10c5458126d90caf882d5a
Author: Benjamin Schubert <co...@benschubert.me>
AuthorDate: Thu Oct 10 15:19:37 2019 +0100

    element.py: Extract __expand_splits to a cython module
    
    __expand_splits takes roughly 4% of our runtime in our benchmarks.
    
    Moving it to cython allows us to regain part of this time and speeds
    up all buildstream's invocations.
    
    - export _variables symbols for cython
    - introduce _element.pyx for cython extension of element.py
---
 setup.py                       |  1 +
 src/buildstream/_element.pyx   | 37 +++++++++++++++++++++++++++++++++++++
 src/buildstream/_variables.pxd | 26 ++++++++++++++++++++++++++
 src/buildstream/_variables.pyx |  6 +-----
 src/buildstream/element.py     | 18 ++----------------
 5 files changed, 67 insertions(+), 21 deletions(-)

diff --git a/setup.py b/setup.py
index 19779fb..e0d3dcd 100755
--- a/setup.py
+++ b/setup.py
@@ -403,6 +403,7 @@ def register_cython_module(module_name, dependencies=None):
 BUILD_EXTENSIONS = []
 
 register_cython_module("buildstream.node")
+register_cython_module("buildstream._element", dependencies=["buildstream.node", "buildstream._variables"])
 register_cython_module("buildstream._loader._loader")
 register_cython_module("buildstream._loader.loadelement")
 register_cython_module("buildstream._loader.types", dependencies=["buildstream.node"])
diff --git a/src/buildstream/_element.pyx b/src/buildstream/_element.pyx
new file mode 100644
index 0000000..f4e2011
--- /dev/null
+++ b/src/buildstream/_element.pyx
@@ -0,0 +1,37 @@
+#
+#  Copyright (C) 2018 Bloomberg Finance LP
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
+#
+from .node cimport MappingNode, SequenceNode
+from ._variables cimport Variables
+
+
+# Expand the splits in the public data using the Variables in the element
+def expand_splits(MappingNode element_public not None, Variables variables not None):
+    cdef MappingNode element_bst = element_public.get_mapping('bst', default={})
+    cdef MappingNode element_splits = element_bst.get_mapping('split-rules', default={})
+    cdef str domain
+    cdef list new_splits
+    cdef SequenceNode splits
+
+    # Resolve any variables in the public split rules directly
+    for domain, splits in element_splits.items():
+        new_splits = [
+            variables.subst(split.strip())
+            for split in splits.as_str_list()
+        ]
+        element_splits[domain] = new_splits
+
+    return element_public
diff --git a/src/buildstream/_variables.pxd b/src/buildstream/_variables.pxd
new file mode 100644
index 0000000..28f9507
--- /dev/null
+++ b/src/buildstream/_variables.pxd
@@ -0,0 +1,26 @@
+#
+#  Copyright (C) 2018 Bloomberg Finance LP
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
+#
+from .node cimport MappingNode
+
+cdef class Variables:
+    cdef MappingNode original
+    cdef dict _expstr_map
+    cdef public dict flat
+
+    cpdef subst(self, str string)
+    cdef dict _resolve(self, MappingNode node)
+    cdef dict _flatten(self)
diff --git a/src/buildstream/_variables.pyx b/src/buildstream/_variables.pyx
index f8662ac..d5db8cd 100644
--- a/src/buildstream/_variables.pyx
+++ b/src/buildstream/_variables.pyx
@@ -65,10 +65,6 @@ PARSE_EXPANSION = re.compile(r"\%\{([a-zA-Z][a-zA-Z0-9_-]*)\}")
 #
 cdef class Variables:
 
-    cdef MappingNode original
-    cdef dict _expstr_map
-    cdef public dict flat
-
     def __init__(self, MappingNode node):
         self.original = node
         self._expstr_map = self._resolve(node)
@@ -87,7 +83,7 @@ cdef class Variables:
     # Raises:
     #    LoadError, if the string contains unresolved variable references.
     #
-    def subst(self, str string):
+    cpdef subst(self, str string):
         expstr = _parse_expstr(string)
 
         try:
diff --git a/src/buildstream/element.py b/src/buildstream/element.py
index 966f0f7..e22495f 100644
--- a/src/buildstream/element.py
+++ b/src/buildstream/element.py
@@ -95,6 +95,7 @@ from ._exceptions import BstError, LoadError, LoadErrorReason, ImplError, \
 from .utils import FileListResult
 from . import utils
 from . import _cachekey
+from . import _element  # type: any
 from . import _signals
 from . import _site
 from ._platform import Platform
@@ -318,7 +319,7 @@ class Element(Plugin):
 
         # Grab public domain data declared for this instance
         unexpanded_public = self.__extract_public(meta)
-        self.__public = self.__expand_splits(unexpanded_public)
+        self.__public = _element.expand_splits(unexpanded_public, self.__variables)
         self.__dynamic_public = None
 
         # Collect the composited element configuration and
@@ -2846,21 +2847,6 @@ class Element(Plugin):
 
         return element_public
 
-    # Expand the splits in the public data using the Variables in the element
-    def __expand_splits(self, element_public):
-        element_bst = element_public.get_mapping('bst', default={})
-        element_splits = element_bst.get_mapping('split-rules', default={})
-
-        # Resolve any variables in the public split rules directly
-        for domain, splits in element_splits.items():
-            splits = [
-                self.__variables.subst(split.strip())
-                for split in splits.as_str_list()
-            ]
-            element_splits[domain] = splits
-
-        return element_public
-
     def __init_splits(self):
         bstdata = self.get_public_data('bst')
         splits = bstdata.get_mapping('split-rules')