[IMP] base: fast special cases in node modifiers
The parsing of the values of attributes `attrs`, `states`, `invisible`, `readonly` and `required` is done many times during the post-processing of a view. The functions `ast.literal_eval` and `safe_eval`, although being pretty cheap, are called so many times that they represent about 10% of the time spent in `field_view_get()`. The variables of the function were poorly named, we take this commit opportunity to rename them: `a` => `attr`, `v` => `value`. After analysis of what was evaluated, it turned out that 95% of the expressions safe-evaluated were '1', '0', 'True' and 'False'. We introduced the special cases to quickly bypass the evaluation and speed up the rendering. Using our benchmark (render_all_view test-tag with website_sale, mrp, contacts, crm and timesheet installed) the runtimes are 27.58s without this commit and 27.45s with. Task: 2495504
This commit is contained in:
@@ -74,18 +74,25 @@ def transfer_node_to_modifiers(node, modifiers, context=None, current_node_path=
|
||||
else:
|
||||
modifiers['invisible'] = [('state', 'not in', node.get('states').split(','))]
|
||||
|
||||
for a in ('invisible', 'readonly', 'required'):
|
||||
if node.get(a):
|
||||
v = bool(safe_eval.safe_eval(node.get(a), {'context': context or {}}))
|
||||
for attr in ('invisible', 'readonly', 'required'):
|
||||
value_str = node.get(attr)
|
||||
if value_str:
|
||||
# most (~95%) elements are 0/1/True/False
|
||||
if value_str == '1' or value_str == 'True':
|
||||
value = True
|
||||
elif value_str == '0' or value_str == 'False':
|
||||
value = False
|
||||
else:
|
||||
value = bool(safe_eval.safe_eval(value_str, {'context': context or {}}))
|
||||
node_path = current_node_path or ()
|
||||
if 'tree' in node_path and 'header' not in node_path and a == 'invisible':
|
||||
if 'tree' in node_path and 'header' not in node_path and attr == 'invisible':
|
||||
# Invisible in a tree view has a specific meaning, make it a
|
||||
# new key in the modifiers attribute.
|
||||
modifiers['column_invisible'] = v
|
||||
elif v or (a not in modifiers or not isinstance(modifiers[a], list)):
|
||||
modifiers['column_invisible'] = value
|
||||
elif value or (attr not in modifiers or not isinstance(modifiers[attr], list)):
|
||||
# Don't set the attribute to False if a dynamic value was
|
||||
# provided (i.e. a domain from attrs or states).
|
||||
modifiers[a] = v
|
||||
modifiers[attr] = value
|
||||
|
||||
|
||||
def simplify_modifiers(modifiers):
|
||||
|
||||
Reference in New Issue
Block a user