[schema] Cache RQL expressions on schema loading
authorPhilippe Pepiot <philippe.pepiot@logilab.fr>
Mon, 30 May 2016 17:41:12 +0200
changeset 11344 847ab4bdd985
parent 11343 892e4c12f03f
child 11345 27b98f3cceae
[schema] Cache RQL expressions on schema loading Add a mapping rql string to rql statement Deserializing schema is ~36% faster with a lot (> 4000) expressions like those generated by cubicweb-container.
cubicweb/schema.py
--- a/cubicweb/schema.py	Tue Jun 07 12:04:21 2016 +0200
+++ b/cubicweb/schema.py	Mon May 30 17:41:12 2016 +0200
@@ -203,6 +203,17 @@
     # to be defined in concrete classes
     predefined_variables = None
 
+    # Internal cache for parsed expressions
+    _rql_cache = {}
+
+    @classmethod
+    def _cached_parse(cls, rql):
+        try:
+            return cls._rql_cache[rql]
+        except KeyError:
+            cls._rql_cache[rql] = parse(rql, print_errors=False).children[0]
+            return cls._rql_cache[rql]
+
     def __init__(self, expression, mainvars, eid):
         """
         :type mainvars: sequence of RQL variables' names. Can be provided as a
@@ -220,7 +231,7 @@
         self.expression = normalize_expression(expression)
         try:
             # syntax tree used by read security (inserted in queries when necessary)
-            self.snippet_rqlst = parse(self.minimal_rql, print_errors=False).children[0]
+            self.snippet_rqlst = self._cached_parse(self.minimal_rql)
         except RQLSyntaxError:
             raise RQLSyntaxError(expression)
         for mainvar in mainvars:
@@ -263,6 +274,7 @@
 
     @cachedproperty
     def rqlst(self):
+        # Don't use _cached_parse here because the rqlst is modified
         select = parse(self.minimal_rql, print_errors=False).children[0]
         defined = set(split_expression(self.expression))
         for varname in self.predefined_variables: