[FIX] mail: fix performance issue on activities filter

Accessing `valid_docs.ids` for each activity to check was costly, and in
my example the whole loop took 125 seconds to execute.

By turning it into a set, the same loop takes 0.2 seconds to execute.

When re-constructing the list based on ids to keep the order, using a
set is also faster, and takes another 0.2 seconds instead of 13.6.

closes odoo/odoo#79969

X-original-commit: f994db760b679c8acdaf4245315f89c1d31a9e1c
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Paul Morelle
2021-11-17 17:26:05 +00:00
parent 1d86447395
commit d271f6a2c2
+4 -3
View File
@@ -363,7 +363,7 @@ class MailActivity(models.Model):
for activity in activities_to_check:
activity_to_documents.setdefault(activity['res_model'], list()).append(activity['res_id'])
allowed_ids = []
allowed_ids = set()
for doc_model, doc_ids in activity_to_documents.items():
# fall back on related document access right checks. Use the same as defined for mail.thread
# if available; otherwise fall back on read
@@ -375,9 +375,10 @@ class MailActivity(models.Model):
right = DocumentModel.check_access_rights(doc_operation, raise_exception=False)
if right:
valid_docs = DocumentModel.browse(doc_ids)._filter_access_rules(doc_operation)
allowed_ids += [
valid_doc_ids = set(valid_docs.ids)
allowed_ids.update(
activity['id'] for activity in activities_to_check
if activity['res_model'] == doc_model and activity['res_id'] in valid_docs.ids]
if activity['res_model'] == doc_model and activity['res_id'] in valid_doc_ids)
if count:
return len(allowed_ids)