[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.
--- 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: