[IMP] base: make recompute faster

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 <rco@odoo.com>
This commit is contained in:
Rémy Voet (ryv)
2022-02-23 10:02:00 +00:00
parent 041fe5e21e
commit 59ea46c97e
+6 -13
View File
@@ -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