Projet

Général

Profil

Development #35437

perfs affichage tableau de demande

Ajouté par Frédéric Péters il y a plus de 4 ans. Mis à jour il y a plus de 4 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Version cible:
-
Début:
19 août 2019
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Le code est commun pickle/sql, gagnerait à avoir du bout spécifique sql pour accélérer les choses.


Fichiers

Révisions associées

Révision 5626fc64 (diff)
Ajouté par Frédéric Péters il y a plus de 4 ans

perfs: use a dictionary to create sorted list of formdatas (#35437)

Historique

#1

Mis à jour par Frédéric Péters il y a plus de 4 ans

Analyse de FormDefUI.get_listing_items, sur ~80k demandes, version annotée avec des timings :

# t0
        formdata_class = self.formdef.data_class()
        if selected_filter == 'all':
            item_ids = formdata_class.keys()
# 0.193354845047
            drafts = formdata_class.get_ids_with_indexed_value('status', 'draft')
# 0.476522922516
            item_ids = [x for x in item_ids if x not in drafts]
# 2.81536078453
        elif selected_filter == 'waiting':
            [...]

        if query: [...]

        if criterias: [...]

        if item_ids and not anonymise:
            # as we are in the backoffice, we don't have to care about the
            # situation where the user is the submitter, and we limit ourselves
            # to consider treating roles.
            if not user.is_admin:
                user_roles = set(user.roles or [])
                concerned_ids = set()
# 2.81542086601
                for role in user_roles:
                    concerned_ids |= set(formdata_class.get_ids_with_indexed_value(
                        'concerned_roles', str(role)))
                item_ids = list(set(item_ids).intersection(concerned_ids))
# 2.81543898582

        [...]

        if order_by and not anonymise:
            ordered_ids = formdata_class.get_sorted_ids(order_by)
# 2.95291399956
            new_item_ids = []
            for item_id in ordered_ids:
                if item_id in item_ids:
                    new_item_ids.append(item_id)
            item_ids = new_item_ids
# 44.4523539543
        else:
            [...]
        [...]
        if limit:
            items = formdata_class.get_ids(item_ids[offset:offset+limit],
                    keep_order=True)
# 44.4615588188

Et donc, plutôt une surprise, c'est ici que tout s'écroule :

            new_item_ids = []
            for item_id in ordered_ids:
                if item_id in item_ids:
                    new_item_ids.append(item_id)
            item_ids = new_item_ids
#2

Mis à jour par Frédéric Péters il y a plus de 4 ans

Et donc sans aller chercher loin SQL comme je l'imaginais dans la description du ticket, simplement passer par un dictionnaire, pour optimiser le "in" :

            item_ids_dict = {x: True for x in item_ids}
            item_ids = [x for x in ordered_ids if x in item_ids_dict]

réduit cette étape de +40 secondes à 0,015 secondes.

#4

Mis à jour par Thomas Noël il y a plus de 4 ans

  • Statut changé de Solution proposée à Solution validée
#5

Mis à jour par Frédéric Péters il y a plus de 4 ans

  • Statut changé de Solution validée à Résolu (à déployer)
commit 5626fc643f79a201c2b3c21d8d111e37a3a3c519
Author: Frédéric Péters <fpeters@entrouvert.com>
Date:   Mon Aug 19 10:55:22 2019 +0200

    perfs: use a dictionary to create sorted list of formdatas (#35437)
#6

Mis à jour par Frédéric Péters il y a plus de 4 ans

  • Statut changé de Résolu (à déployer) à Solution déployée

Formats disponibles : Atom PDF