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 :

améliorer la performance de la recherche des doublons dans un gridview


Sujet :

C#

  1. #1
    Membre régulier
    Inscrit en
    Mars 2003
    Messages
    217
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 217
    Points : 73
    Points
    73
    Par défaut améliorer la performance de la recherche des doublons dans un gridview
    Bonjour,
    J'ai une fonction qui recherche l'indice des doublons présent dans une colonne d'un gridview.
    Code : 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
    Dictionary<string, List<int>> repetitionValue = new Dictionary<string, List<int>>();
                List<int> listValue = new List<int>();
                List<string> key = new List<string>();
                for (int i = 0; i < gridView1.RowCount; i++)
                {
                    //on  traite les lignes autres que les lignes des ID, Name, description 1, description 2
                    if (!indexRow.Values.Contains(i))
                    {
                        if (!key.Contains(gridView1.GetDataRow(i)[nameCol].ToString()))
                        {
                            key.Add(gridView1.GetDataRow(i)[nameCol].ToString());
                            #region vérifier les doublons dans l'index
                            for (int j = i + 1; j < gridView1.RowCount; j++)
                            {
                                if (gridView1.GetDataRow(i)[nameCol].ToString().Equals(gridView1.GetDataRow(j)[nameCol].ToString()))
                                {
                                    listValue.Add(j);
                                }
                            }
     
                            if (listValue.Count > 0)
                            {
                                repetitionValue.Add(gridView1.GetDataRow(i)[nameCol].ToString(), new List<int>(listValue));
                                listValue.Clear();
                            }
                            #endregion
                        }
                    }
                }
                return repetitionValue;
    Avec des données de 58000 lignes, ca me prends beaucoup de temps pour faire la recherche (plus de 3min). J'ai regardé quelques pistes pour essayer de résoudre la perfomance comme l'utilisation de la requete linq dans une collection pour récupérer la valeur en double avant de trouver les indices des doublons. Cet approche présente un problème car on accède pas à la collection de données directement avec la colonne comme c'est le cas avec une ligne.
    Y a t-il un moyen plus efficace pour améliorer la recherche des indices?
    merci pour votre aide

  2. #2
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Si ton datagridview est Bindé il est largement préférable de travailler directement sur la DataSource

    Et si ce n'est pas le cas il y a vraissemblablement un problème de design car gerer directement plus de 50000 dans un datagridview c'est vouloir enfoncer un clou avec un tournevis.
    « Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)

  3. #3
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    L'utilisation de SortedList permettrait d'améliorer largement les performances.

    De plus, "gridView1.GetDataRow(i)[nameCol].ToString()" pourrait être avantageusement remplacé par "gridView1.Rows[i].Cells[ColIndex]" (ColIndex étant fixé avant la boucle).
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  4. #4
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Bonjour

    Je maintiens ce que j'avais dis par rapport a l'usage de la datasource, par contre j'avoue que je n'avais pas bien regardé le code existant et la réponse de grafito m'a mis l'a puce a l'oreille

    Que tu parcours un dgv ou directement la datasource a mon avis ce n'est pas une sortedlist que tu devais utiliser mais un Dictionary, tu effectue une premiere passe en chargeant un dictionary, ensuite tu teste les doublons sur ce dictionary (mais je n'ai pas été tres loin dans l'analyse de ton code)
    « Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)

  5. #5
    Membre régulier
    Inscrit en
    Mars 2003
    Messages
    217
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 217
    Points : 73
    Points
    73
    Par défaut
    Pour information, je ne peux acceder à la cellule que par gridView1.GetDataRow(i)[nameCol].ToString(), car j'utilise gridcontrol de dexexpress et leur gridview est différent.
    Sinon, j'ai pensé à mettre mes données dans un dictionary avec pour key mon numero de ligne et la valeur les données dans ma colonne. Ensuite faire ma recherche en utilisant linq. J'ai quelques problème à ce niveau, j'arrive pas à retourner les valeurs des doublons. qu'est ce que vous en pensez?

  6. #6
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Salut

    Moi j'aurais fais un truc comme ceci (pas compilé ni testé)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
          Dictionary<string, List<int>> DicoDoublons = new Dictionary<string, List<int>>();
          List<int> Doubles = new List<int>();
     
          List<string> key = new List<string>();
          for (int i = 0; i < gridView1.RowCount; i++)
          {
            //on  traite les lignes autres que les lignes des ID, Name, description 1, description 2
            string Key = gridView1.GetDataRow(i)[nameCol].ToString();
            if (!DicoDoublons.ContainsKey(Key))
            {
              DicoDoublons.Add(Key, new List<int>());
            }
            DicoDoublons[Key].Add(i);
          }
    « Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    par lu les réponses déjà postées, mais si tes données viennent d'une base de données il sera nettement plus rapide de chercher les doublons avec une requête !

    par exemple pour des doublons sur 2 champs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select champ1, champ2, count(*) from table group by champ1, champ2 having count(*) > 1
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Membre régulier
    Inscrit en
    Mars 2003
    Messages
    217
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 217
    Points : 73
    Points
    73
    Par défaut
    j'ai essayé ton code, c'est vrai il me fait gagner énorment de temps.
    Code : 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
    for (int i = 0; i < gridView1.RowCount; i++)
                {
                    //on  traite les lignes autres que les lignes des ID, Name, description 1, description 2
                    string Key = gridView1.GetDataRow(i)[nameCol].ToString();
                    if (!repetitionValue.ContainsKey(Key))
                    {
                        repetitionValue.Add(Key, new List<int>());
                    }
                    else
                    {
                        repetitionValue[Key].Add(i);
                    }
                }
     
                for (int i = repetitionValue.Keys.Count-1;i>=0;i--)
                {
                    if (repetitionValue.Values.ElementAt(i).Count == 0)
                    {
                        repetitionValue.Remove(repetitionValue.Keys.ElementAt(i));
                    }
    J'imagine qu'on peut améliorer encore un peu la performance en éliminant la boucle qui supprime les données qui ne possèdent pas de doublons. Je pense qu'on peut le faire avec la fonction groupby du dictionary.

    Pour Pol63, non mes données sont dans un gridview mais je cherche un moyen pour transformer ta requête pour l'exécuter dans la variable dictionary

  9. #9
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    A quoi te sert ce remove alambiqué et délicat ?

    En parcourant ton dictionaire tu peux rapidement constituer une nouvelle liste ou un dictionaire de ce qui t'intéresse.

    Ou simplement l'utiliser tel quel pour ce que tu dois faire
    « Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)

  10. #10
    Membre régulier
    Inscrit en
    Mars 2003
    Messages
    217
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 217
    Points : 73
    Points
    73
    Par défaut
    C'est ce que je veux faire, me créer une nouvelle dictionaire c'est pour ca que j'utilise ma 2eme boucle, mais je sais qu'il y a un moyen d' y arriver sans la boucle. J'ai essayé avec le groupby du dictionary mais je pense que ma syntaxe n'est pas bon

  11. #11
    Membre expérimenté
    Avatar de jbrasselet
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2006
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 022
    Points : 1 413
    Points
    1 413
    Par défaut
    Je ne sais pas dans quelle version du framework tu es mais avec une requête linq tu devrais t'en tirer
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai.

  12. #12
    Membre régulier
    Inscrit en
    Mars 2003
    Messages
    217
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 217
    Points : 73
    Points
    73
    Par défaut
    Bon j'ai réuissi à optimiser le code en enlevant le second boucle qui supprimait les données unique dans le datatable. J'ai utilisé la requête linq
    Code : 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
    for (int i = 0; i < gridView1.RowCount; i++)
                {
                    if (!indexRow.Values.Contains(i))
                    {
                        //on  traite les lignes autres que les lignes des ID, Name, description 1, description 2
                        string Key = gridView1.GetDataRow(i)[nameCol].ToString();
                        if (!repetitionValue.ContainsKey(Key))
                        {
                            repetitionValue.Add(Key, new List<int>());
                        }
                        else
                        {
                            repetitionValue[Key].Add(i);
                        }
                    }
                }
                repetitionValue = (from t in repetitionValue where t.Value.Count > 0 select t).ToDictionary(x=>x.Key,x=>x.Value);
    merci pour l'aide que vous avez apporté

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

Discussions similaires

  1. Rechercher des doublons dans ACCESS(quasi doublons)
    Par ingal30 dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 10/03/2010, 13h57
  2. Réponses: 7
    Dernier message: 09/02/2009, 14h28
  3. Rechercher des doublons dans un fichier de type csv
    Par phoenixatareva dans le forum C++
    Réponses: 6
    Dernier message: 12/08/2008, 20h02
  4. Réponses: 0
    Dernier message: 02/10/2007, 13h44
  5. recherche des doublons dans une hash
    Par Jasmine80 dans le forum Langage
    Réponses: 4
    Dernier message: 29/01/2007, 11h51

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