IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Problème performance de liste


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2010
    Messages
    336
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2010
    Messages : 336
    Par défaut Problème performance de liste
    Bonjour,

    j'aurai besoin de votre aide. En effet, je rencontre un problème de performance lorsque je construit une large liste d'objet. Au niveau de la récupération des données depuis la base de données c'est rapide mais lorsque je construit ma liste cela deviens extrêmement long. Selon le nombre d'enregistrement que je peux récupérer, cela peux aller jusque 300K records. Je vous laisse imaginer ... Je me suis dit pour tester je vais limiter à 5k records mais cela dure : Temps execution :00:03:18.9387725 minutes

    Pour info : l'accès DB se fait avec Entity Framework.

    Voici le code :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    public static List<DisplayRecherche> ChercheById(long id, string operateur)
            {
                DateTime date = DateTime.Now;
                IQueryable<DODON00> query = null;
                List<DODON00> results = null;
     
                switch (operateur)
                {
                    case "=":
                        query = ctx.DODON00.Where(x => x.DONSEQ == id);
                        break;
                    case "<>":
                        query = ctx.DODON00.Where(x => x.DONSEQ != id);
                        break;
                    case "<":
                        query = ctx.DODON00.Where(x => x.DONSEQ < id);
                        break;
                    case "<=":
                        query = ctx.DODON00.Where(x => x.DONSEQ <= id);
                        break;
                    case ">":
                        query = ctx.DODON00.Where(x => x.DONSEQ > id);
                        break;
                    case ">=":
                        query = ctx.DODON00.Where(x => x.DONSEQ >= id);
                        break;
                }
                results = query.Take(5000).ToList();
                List<DisplayRecherche> recherche = results.Select(x => new DisplayRecherche()
                {
                    DONENT = GetDatetimeFromDONENT(x.DONENT),
                    DONPRD = x.DONPRD,
                    DONSEQ = x.DONSEQ,
                    LIBLIB = GetLIBLIB(x.DONSEQ)
                }).ToList();
     
                TimeSpan tempExec = DateTime.Now - date;
                Debug.WriteLine("Temps execution :" + tempExec.ToString());
                return recherche;
            }
     
            public static string GetLIBLIB(decimal id)
            {
                string cle = id.ToString("0000000000");
                return ctx.PALIB00.SingleOrDefault(x => x.LIBCLE.Equals(cle)).LIBLIB;
            }
     
            private static DateTime GetDatetimeFromDONENT(decimal donent)
            {
                return new DateTime((int)(donent / 10000), (int)((donent / 100) % 100), (int)(donent % 100));
            }

    De ce que j'ai pu comprendre c'est vraiment cette partie qui prend un temps fou ...
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    List<DisplayRecherche> recherche = results.Select(x => new DisplayRecherche()
                {
                    DONENT = GetDatetimeFromDONENT(x.DONENT),
                    DONPRD = x.DONPRD,
                    DONSEQ = x.DONSEQ,
                    LIBLIB = GetLIBLIB(x.DONSEQ)
                }).ToList();

    Mon code est loin d'être parfait, mais je ne vois pas comment optimiser pour que cela soit plus rapide que 3 minutes pour charger 5k record dans une liste ... Surtout si j'en ai les 300k.

  2. #2
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    3 010
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 010
    Par défaut
    Ce qui prend du temps, c'est l'exécution des 5000 requêtes supplémentaires induites par cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ctx.PALIB00.SingleOrDefault(x => x.LIBCLE.Equals(cle)).LIBLIB;
    Il doit y avoir un moyen de s'en sortir avec une jointure.

  3. #3
    Membre très actif
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2010
    Messages
    336
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2010
    Messages : 336
    Par défaut
    Bonjour popo,

    j'ai adapté de cette manière :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    DateTime date = DateTime.Now;
                IQueryable<DODON00> query = null;
                IQueryable<PALIB00> query2 = null;
     
                switch (operateur)
                {
                    case "=":
                        query = ctx.DODON00.Where(x => x.DONSEQ == id);
                        break;
                    case "<>":
                        query = ctx.DODON00.Where(x => x.DONSEQ != id);
                        break;
                    case "<":
                        query = ctx.DODON00.Where(x => x.DONSEQ < id);
                        break;
                    case "<=":
                        query = ctx.DODON00.Where(x => x.DONSEQ <= id);
                        break;
                    case ">":
                        query = ctx.DODON00.Where(x => x.DONSEQ > id);
                        break;
                    case ">=":
                        query = ctx.DODON00.Where(x => x.DONSEQ >= id);
                        break;
                }
    string cle = id.ToString("0000000000");
    query2 = ctx.PALIB00.Where(x => x.LIBCLE == cle);
    var joinedQuery = from d in query
                                  join p in query2 on ((int)d.DONSEQ).ToString("0000000000") equals p.LIBCLE
                                  select new DisplayRecherche
                                  {
                                      DONENT = GetDatetimeFromDONENT(d.DONENT),
                                      DONPRD = d.DONPRD,
                                      DONSEQ = (long)d.DONSEQ,
                                      LIBLIB = p.LIBLIB
                                  };
     
                Debug.WriteLine("Temps execution :" + (TimeSpan)(DateTime.Now - date));
                List<DisplayRecherche> lst = null;
                try
                {
                    lst = joinedQuery.Take(5000).ToList();
                }
                catch (Exception ex) { }
     
                return lst;
    Mais j'ai cette erreur :

    System.NotSupportedException*: 'LINQ to Entities ne reconnaît pas la méthode 'System.String ToString(System.String)', et cette dernière ne peut pas être traduite en expression de magasin.'

    J'avoue que je suis perdu... Après, DONSEQ est decimal dans la DB et LIBCLE est un string sur 10 positions. Je ne suis pas propriétaire de la base et n'ai accès qu'en lecture seule donc je ne sais pas changé les types de la db ...

  4. #4
    Membre très actif
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2010
    Messages
    336
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2010
    Messages : 336
    Par défaut
    J'ai changé mon code en faisant du sql pur.
    ChatGPT ma généré ce que je voulais et la récupération des 300k record dans une liste + rendu sur la vue me prend maintenant 7 secondes.
    Merci !

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 586
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 586
    Par défaut
    donc pour info, ça donne quoi en code ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème incompréhensible! Fichier + liste
    Par djsbens dans le forum C
    Réponses: 2
    Dernier message: 07/12/2005, 00h30
  2. Réponses: 7
    Dernier message: 21/11/2005, 14h21
  3. [STL]Problème itérateur avec list
    Par Fiquet dans le forum SL & STL
    Réponses: 7
    Dernier message: 03/10/2005, 17h54
  4. Problème performance SELECT avec jointure
    Par Netgamer dans le forum Requêtes
    Réponses: 7
    Dernier message: 05/08/2005, 10h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo