diff options
| author | Denis Ledoux <dle@odoo.com> | 2019-08-22 11:29:38 +0000 |
|---|---|---|
| committer | Raphael Collet <rco@odoo.com> | 2019-09-11 07:55:17 +0000 |
| commit | 3d1c924cffd839c076d9bacaf8bab9d995aee01e (patch) | |
| tree | f9b0929cfd8f14ddc7f4056d530a95473f4b0f8c /odoo | |
| parent | 0e028de72ea0f49586790b580774bac203a8ed96 (diff) | |
[FIX] fields.py: improve computation time of records having a different value in cache
Instead of using a filtered with `cache.get`,
use a dedicated method in the Cache class to get
the records having a different value in cache then asked.
This is mainly to avoid the creation of intermediate
`browse` of 1 record, when doing `for rec in self`
in `filtered`.
Creating browses is costly, and avoiding it leads
to performance gains.
The dedicated method `get_records_different_from`
loops on the record ids, instead of on browse records
Diffstat (limited to 'odoo')
| -rw-r--r-- | odoo/api.py | 18 | ||||
| -rw-r--r-- | odoo/fields.py | 12 |
2 files changed, 22 insertions, 8 deletions
diff --git a/odoo/api.py b/odoo/api.py index 1bba63b4400..65ae87f2b92 100644 --- a/odoo/api.py +++ b/odoo/api.py @@ -766,6 +766,24 @@ class Cache(object): except KeyError: pass + def get_records_different_from(self, records, field, value): + """ Return the subset of ``records`` that has not ``value`` for ``field``. """ + field_cache = self._data[field] + key = self._get_context_key(records.env, field) if field.depends_context else None + ids = [] + for record_id in records._ids: + try: + if key: + val = field_cache[record_id][key] + else: + val = field_cache[record_id] + except KeyError: + ids.append(record_id) + else: + if val != value: + ids.append(record_id) + return records.browse(ids) + def get_fields(self, record): """ Return the fields with a value for ``record``. """ for name, field in record._fields.items(): diff --git a/odoo/fields.py b/odoo/fields.py index 9e285517674..e82bc06ee98 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -967,9 +967,8 @@ class Field(MetaField('DummyField', (object,), {})): # update the cache, and discard the records that are not modified cache = records.env.cache - NOTHING = object() cache_value = self.convert_to_cache(value, records) - records = records.filtered(lambda record: cache.get(record, self, NOTHING) != cache_value) + records = cache.get_records_different_from(records, self, cache_value) if not records: return records cache.update(records, self, [cache_value] * len(records)) @@ -1386,9 +1385,8 @@ class _String(Field): # update the cache, and discard the records that are not modified cache = records.env.cache - NOTHING = object() cache_value = self.convert_to_cache(value, records) - records = records.filtered(lambda record: cache.get(record, self, NOTHING) != cache_value) + records = cache.get_records_different_from(records, self, cache_value) if not records: return records cache.update(records, self, [cache_value] * len(records)) @@ -1912,9 +1910,8 @@ class Binary(Field): # update the cache, and discard the records that are not modified cache = records.env.cache - NOTHING = object() cache_value = self.convert_to_cache(value, records) - records = records.filtered(lambda record: cache.get(record, self, NOTHING) != cache_value) + records = cache.get_records_different_from(records, self, cache_value) if not records: return records cache.update(records, self, [cache_value] * len(records)) @@ -2396,9 +2393,8 @@ class Many2one(_Relational): # discard the records that are not modified cache = records.env.cache - NOTHING = object() cache_value = self.convert_to_cache(value, records) - records = records.filtered(lambda record: cache.get(record, self, NOTHING) != cache_value) + records = cache.get_records_different_from(records, self, cache_value) if not records: return records |
