From 59ea46c97e004607744d4756dc16c98df633f427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Voet=20=28ryv=29?= Date: Mon, 14 Feb 2022 14:24:12 +0000 Subject: [PATCH] [IMP] base: make `recompute` faster MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we read data of one record, the method `recompute` (`_fetch_field` -> `_read` -> `flush` -> `recompute`) can take more than 40 % of the time of the `_read`, due to a huge number of recordset creation (from `records_to_compute` and `records & recs`). Avoid that waste of time by postponing the test on records. For example, on a database with modules crm, mrp, purchase, website, sale_management, reading the prefetchable fields of the current company took 1.45 ms ± 60.3 µs, and now takes 1.17 ms ± 110 µs (more than 20% speedup). closes odoo/odoo#83818 Related: odoo/enterprise#24645 Signed-off-by: Raphael Collet --- odoo/models.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/odoo/models.py b/odoo/models.py index 8eb1f5ad2c3..a3a7688d545 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -6141,9 +6141,9 @@ Fields: """ def process(field): recs = self.env.records_to_compute(field) - if not recs: + if (not recs) or (records is not None and not (records & recs)): return - if field.compute and field.store: + if field.store: # do not force recomputation on new records; those will be # recomputed by accessing the field on the records recs = recs.filtered('id') @@ -6166,18 +6166,11 @@ Fields: for field in list(self.env.fields_to_compute()): process(field) else: - fields = [self._fields[fname] for fname in fnames] - - # check whether any 'records' must be computed - if records is not None and not any( - records & self.env.records_to_compute(field) - for field in fields - ): - return - # recompute the given fields on self's model - for field in fields: - process(field) + for fname in fnames: + field = self._fields[fname] + if field.compute: + process(field) # # Generic onchange method