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 :

[DataSet] Comparaison très lente


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2008
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Janvier 2008
    Messages : 106
    Par défaut [DataSet] Comparaison très lente
    Bonjour,

    Je suis en train de programmer un synchronisateur qui prend les données d'une base de données Acomba et les insert dans une base de données MySQL. Jusque la, tout est parfait. Mon problème arrive par la suite.

    Je dois comparer les données de ces base de données. J'ai donc rempli 2 DataSet et je compare mais cela est très mais très lent. J'ai prêt de 18,000 lignes et 155 colonnes (donc beaucoup de données) dans un DataSet et l'autre est vide alors il ca ne devrait pas être très long lors de la comparaison. C'est peut-être moi qui m'y prend mal mais la je ne sais plus du tout comment faire pour que cela sois un minimum rapide.

    Merci,
    Friedrick

    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
     
    private void firstpass(ref DataSet ds1, string pk1, ref DataSet ds2, string pk2)
    {
        //ds1 has priority
        for (int x = 0; x < ds1.Tables[0].Rows.Count; x++)
        {
            //check if row exist in ds2
            if (!this.isin(ds2, ds1.Tables[0].Rows[x][pk1].ToString(), pk2))
            {
                //primary key of ds1 does not match ds2
                DataRow newrow = ds2.Tables[0].NewRow();
                for (int c = 0; c < ds2.Tables[0].Columns.Count; c++)
                {
                    newrow[c] = ds1.Tables[0].Rows[x][c];
                    logBox.Text += ">>>New Data : " + ds1.Tables[0].Rows[x][c].ToString() + "\n";
                    scroll();
                }
                ds2.Tables[0].Rows.Add(newrow);
                //newrow.Delete();
            }
        }
    }

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    fait voir le code de ta méthode isin aussi

    pourquoi convertir la clé primaire en string pour la passer en paramètre de isin ?

    à mon avis ce qui est lent c'est surtout ta façon de copier les lignes, et la mise à jour de l'interface

    - pas la peine de copier colonne par colonne, il y a des moyens plus simples :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ds2.Tables[0].Rows.Add(ds1.Tables[0].Rows[x].ItemArray);
    - tu modifies un textbox dans une boucle où l'exécution va passer 155 * 18000 = 2790000 fois... Tu as vraiment besoin de logger chaque colonne de chaque ligne ? Pour quoi faire ? Tu vas vérifier visuellement les 2790000 lignes de log ?

  3. #3
    Membre confirmé
    Inscrit en
    Janvier 2008
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Janvier 2008
    Messages : 106
    Par défaut
    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
     
    private bool isin(DataSet dsin, string pk, string pkfield)
    {
        //get collumn index
     
        for (int x = 0; x < dsin.Tables[0].Rows.Count; x++)
        {
            string t = dsin.Tables[0].Rows[x][pkfield].ToString();
     
            /*
             * check if pk or t are double or int convert both to double
             * and back to string
             */
            try
            { //pk is double
                pk = Double.Parse(pk).ToString();
                t = Double.Parse(t).ToString();
            }
            catch { }
     
            if (String.Compare(t, pk, true) == 0)
                return true;
        }
        return false;
    }
    Voici ma méthode isin. Non, je ne suis pas oublier de tout mettre dans un textbox, c'était simplement pour me débugger. Sinon, je n'ai aucune idée pourquoi la clé est changer en string. J'ai prit le code de mon collègue, car c'est lui qui l'a créer mais il nous a quitter alors, je ramasse les pots cassés . Non, sans rire, le programme original était en console et son système de configuration passait par des fichiers .dat sans aucune façon de modifier les DSN, les tables à sync, etc. J'ai donc mit un petit visuel simple!


    Merci, pour la façon de copier je ne la connaissais pas! Car le problème aussi c'est qu'il y a trois phase à faire:

    - La première ajouter les lignes de DS1 à DS2;
    - La deuxième supprime les lignes de DS2 qui ne sont pas dans DS1;
    - La troisième modifie le statut pour savoir si modifié, ajouté ou supprimé.

    Voici le code des mes 2 autres méthodes: http://pastebin.com/m2c6de39e

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    private void secondpass(ref DataSet ds1, string pk1, ref DataSet ds2, string pk2)
    {
        //ds1 has priority
        for (int x = 0; x < ds2.Tables[0].Rows.Count; x++)
        {
            //check if row exist in ds2
            if (!this.isin(ds1, ds2.Tables[0].Rows[x][pk2].ToString(), pk1))
            {
     
                //primary key of ds1 does not match ds2
                Console.WriteLine(">>>Deleting Data : " + ds2.Tables[0].Rows[x].ToString());
                ds2.Tables[0].Rows[x].Delete();
            }
        }
    }
    private void thirdpasss(ref DataSet ds1, string pk1,string[] fields1, ref DataSet ds2, string pk2,string[] fields2){
        /* if rowcount ds1 != ds2 throw
         * here we have to compare all row from ds1 to ds2,
         * for each row in ds1,
         *    for each field in fieldsa
         *    if ds2[row][fieldsb[index of fielda]] != ds1[row][field]
         *    ds2[row][[fieldsb[index of fielda]] = ds1[row][field]
         */
     
        if (this.getrcount(ds1) != this.getrcount(ds2))
            throw new ApplicationException("Row count dont match, cannot synchronize.Rerun pass 1 and 2");
        if (fields1.Count() != fields2.Count())
            throw new ApplicationException("fields count dont match, cannot synchronize.Check config");
        for (int r1=0; r1 < ds1.Tables[0].Rows.Count; r1++){
            if (ds1.Tables[0].Rows[r1].RowState == DataRowState.Deleted)
                continue;
            for (int f1 = 0; f1 < fields1.Count(); f1++){
                //first ensure that ds1 pk is in ds2
                // then get index of ds2
                //int r2index = this.getindex(ds2, ds1.Tables[0].Rows[r1][pk1].ToString(),pk1);
                int r2index = 0;
                if (r2index == -1)
                    throw new ApplicationException("Trying to synchronize pass 3, row not found in noprio ds, rerun pass1 and 2");
                L(ds2.Tables[0].Rows[0][1].ToString());
                string ds1str = "";
                string ds2str = "";
                ds1str = ds1.Tables[0].Rows[r1][fields1[f1]].ToString();
                ds2str = ds2.Tables[0].Rows[r2index][fields2[f1]].ToString();
                L("*******");
                Console.WriteLine(ds1str.ToString());
                Console.WriteLine(ds2str.ToString());
     
                if ( ds2str != ds1str){
                    Console.WriteLine("Field modified");
                    Console.WriteLine("ds1 :" + ds1.Tables[0].Rows[r1][fields1[f1]].ToString());
                    Console.WriteLine("ds2 :" + ds2.Tables[0].Rows[r2index][fields2[f1]].ToString());
                    ds2.Tables[0].Rows[r2index][fields1[f1]] = ds1.Tables[0].Rows[r1][fields1[f1]].ToString();
     
                }
     
            }
        }
     
    }

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Ben si tu revoies ce collègue un jour, balance lui ce code dans la gueule

    En plus de ceux que j'ai déjà indiqués, il y a un autre gros point de ralentissement dans la méthode isin : la recherche se fait par clé primaire, donc inutile de parcourir toute la table pour retrouver la ligne recherchée... La méthode Select permet d'effectuer une recherche dans une DataTable, et si la colonne est bien définie comme clé primaire, la recherche se fait par un index, donc beaucoup plus rapide (et plus simple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    private bool isin(DataSet dsin, string pk, string pkfield)
    {
        DataRow[] rows = dsin.Tables[0].Select(pkfield + " = " + pk); // par exemple "id = 3"
        return rows.Count > 0;
    }
    Ca devrait déjà pas mal améliorer les performances. Mais à mon avis le plus important reste de dégager les mises à jour d'interfaces qui doivent prendre au moins 80% du temps...

    Mais franchement, je pense qu'au lieu d'essayer de récupérer un code pourri, tu ferais mieux de te former un peu sur l'utilisation des DataSets et de refaire le truc toi-même en repartant de zéro...

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2008
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Janvier 2008
    Messages : 106
    Par défaut
    Merci pour ton aide! Je viens de faire les modifications et je test. J'ai repris l'application originale en mode console sans aucun debug alors cela devrait accéléré le processus.

    Pour ce qui est d'apprendre les DataSet, ouais c'est dans mes plans, mais la on manque de temps pour ce projet alors je fais mon possible .

    Je te redonnes des nouvelles et encore merci!

    Merci, Frédérick.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Au fait, tu as regardé la méthode DataSet.Merge ?
    Je sais pas si ça correspond à ton besoin, mais ça vaut le coup d'y jeter un oeil...

Discussions similaires

  1. BDD sur réseau très très très lent...
    Par ericain dans le forum Access
    Réponses: 12
    Dernier message: 20/02/2015, 18h17
  2. Ouverture et fermeture de base très lent...
    Par Tofdelille dans le forum Installation
    Réponses: 6
    Dernier message: 19/09/2006, 19h51
  3. [Lomboz] Editeur jsp très lent
    Par lr dans le forum Eclipse Java
    Réponses: 10
    Dernier message: 29/01/2005, 20h43
  4. SQL Server trés lent
    Par arwen dans le forum MS SQL Server
    Réponses: 18
    Dernier message: 07/11/2003, 15h45

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