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 :

Optimisation de code


Sujet :

C#

  1. #1
    Membre à l'essai
    Inscrit en
    Octobre 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 18
    Points : 12
    Points
    12
    Par défaut Optimisation de code
    Bonjour à tous
    Dans mon projet j'ai un DataSet, parmis les datatables de ma DataSet j'ai un datatable intitulé Vols et un DataTable nommé Recette les deux datatables contiennent en moyenne 4000 enregistrements .
    dans la partial class de ma dataset j'ai une méthode nommée ControlRecette()
    l'exécution de cette méthode est très lente (affaire d'heures !)
    dans cette méthode je parcoure la datatable Recette et de chercher le vol concerné dans la datatable Vols dans le cas où je trouve ce vol je lui affecte sa recette sinon je lui attribut un status de False.

    quelqu'un peut m'aider dans le but d'optimiser ce code



    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
    public void ControlRecette()
            {
                this.Recette.RowChanged -= new DataRowChangeEventHandler(Recette_RowChanged);
                try
                {
                    foreach (RecetteRow MyRecetteRow in this.Recette)
                    {
                        if (this.AnomaliesRef.Rows.Count > 0)
                            Correcte_Villes(MyRecetteRow);
                        VOLSRow[] FoundsRows = (VOLSRow[])this.VOLS.Select("nligne='" + MyRecetteRow.Nligne + "' and date_d='" + MyRecetteRow.Date_D + "' and ville_d='" + MyRecetteRow.Ville_D + "' and ville_r='" + MyRecetteRow.Ville_R + "'");
                        if (FoundsRows.Length > 0)
                        {
                            MyRecetteRow.Status = true;
                            MyRecetteRow.Code_Vol = FoundsRows[0].CODE;
                            MyRecetteRow.Diff_Tot_Pax = Math.Abs(Convert.ToInt32(FoundsRows[0].TOT_PAX - MyRecetteRow.ToT_PAX));
                            FoundsRows[0].Status = true;
                            if (!MyRecetteRow.IsRecette_MslfNull())
                                FoundsRows[0].Recette_Mslf = MyRecetteRow.Recette_Mslf;
                            if (!MyRecetteRow.IsRecette_InterLineNull())
                                FoundsRows[0].Recette_InterLine = MyRecetteRow.Recette_InterLine;
                            if (!MyRecetteRow.IsRecette_CharterNull())
                                FoundsRows[0].Recette_Charter = MyRecetteRow.Recette_Charter;
                            if (!MyRecetteRow.IsRecetteNull())
                                FoundsRows[0].Recette = MyRecetteRow.Recette;
                            FoundsRows[0].Diff_Tot_Pax = Math.Abs(Convert.ToInt32(FoundsRows[0].TOT_PAX - MyRecetteRow.ToT_PAX));
     
                        }
                        else
                        {
                            MyRecetteRow.Status = false;
                            MyRecetteRow.RowError = "Vol non trouvé dans TunStat";
                        }
                    }
                    VOLSRow[] UncheckedVolsFoundsRows = (VOLSRow[])this.VOLS.Select("state=false");
                    foreach (VOLSRow MyVolRow in UncheckedVolsFoundsRows)
                    {
                        MyVolRow.Status = false;
                        MyVolRow.RowError = "Vol non trouvé dans Recette database";
                    }
                }
                finally
                {
                    this.Recette.RowChanged += new DataRowChangeEventHandler(Recette_RowChanged);
                }
     
            }

  2. #2
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Points : 661
    Points
    661
    Par défaut

  3. #3
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Salut.

    As tu essayé de savoir quelle partie de ton code est lent :
    - Le chargement des données dans le dataset ?

    - Le parcours seul des 4000 lignes ?

    - Le select sur les 4000 lignes ?

    - tes algos dans les différentes méthodes de tests ?

  4. #4
    Membre à l'essai
    Inscrit en
    Octobre 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 18
    Points : 12
    Points
    12
    Par défaut
    Salut merci pour ta réponse ,
    Le chargement est très rapide de même pour le parcours des datarows .
    c'est la mise à jours des enregistrements qui est lente.
    en fait j'ai fais un parcours des enregistrements avec les select sans aucune action derière et le temps de réponse est respectable moins d'une minute dès que je fais une mise à jour sur les datarows ça tourne au vinaigre.
    en débugant j'ai vérifié qu'il n'y a aucun évenement genre datarowchanging ou autre qui se déclenche.
    voici le code de test du parcours et du select sans mise à jour des datarows
    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
    public void ControlRecette()
            {
                this.Recette.RowChanged -= new DataRowChangeEventHandler(Recette_RowChanged);
                try
                {
                    foreach (RecetteRow MyRecetteRow in this.Recette)
                    {
                        if (this.AnomaliesRef.Rows.Count > 0)
                            Correcte_Villes(MyRecetteRow);
                        VOLSRow[] FoundsRows = (VOLSRow[])this.VOLS.Select("nligne='" + MyRecetteRow.Nligne + "' and date_d='" + MyRecetteRow.Date_D + "' and ville_d='" + MyRecetteRow.Ville_D + "' and ville_r='" + MyRecetteRow.Ville_R + "'");
                        if (FoundsRows.Length > 0)
                        {
                            //MyRecetteRow.Status = true;
                            //MyRecetteRow.Code_Vol = FoundsRows[0].CODE;
                            //MyRecetteRow.Diff_Tot_Pax = Math.Abs(Convert.ToInt32(FoundsRows[0].TOT_PAX - MyRecetteRow.ToT_PAX));
                            //FoundsRows[0].Status = true;
                            //if (!MyRecetteRow.IsRecette_MslfNull())
                            //    FoundsRows[0].Recette_Mslf = MyRecetteRow.Recette_Mslf;
                            //if (!MyRecetteRow.IsRecette_InterLineNull())
                            //    FoundsRows[0].Recette_InterLine = MyRecetteRow.Recette_InterLine;
                            //if (!MyRecetteRow.IsRecette_CharterNull())
                            //    FoundsRows[0].Recette_Charter = MyRecetteRow.Recette_Charter;
                            //if (!MyRecetteRow.IsRecetteNull())
                            //    FoundsRows[0].Recette = MyRecetteRow.Recette;
                            //FoundsRows[0].Diff_Tot_Pax = Math.Abs(Convert.ToInt32(FoundsRows[0].TOT_PAX - MyRecetteRow.ToT_PAX));
     
                        }
                        else
                        {
                            //MyRecetteRow.Status = false;
                            //MyRecetteRow.RowError = "Vol non trouvé dans TunStat";
                        }
                    }
                    //VOLSRow[] UncheckedVolsFoundsRows = (VOLSRow[])this.VOLS.Select("state=false");
                    //foreach (VOLSRow MyVolRow in UncheckedVolsFoundsRows)
                    //{
                    //    MyVolRow.Status = false;
                    //    MyVolRow.RowError = "Vol non trouvé dans Recette database";
                    //}
                }
                finally
                {
                    this.Recette.RowChanged += new DataRowChangeEventHandler(Recette_RowChanged);
                }
     
            }
    le temps de répose est de queleques secondes
    Le même algorithme est appliqué ailleur est donne un bon temps de réponse.
    A+

  5. #5
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    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 177
    Points : 25 125
    Points
    25 125
    Par défaut
    ca sent le code qui pourrait se trouver dans une procédure stockée SQL
    et ca prendrait quelques secondes au lieu de quelques heures ...

  6. #6
    Membre à l'essai
    Inscrit en
    Octobre 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 18
    Points : 12
    Points
    12
    Par défaut
    En fait les données ne proviennent pas d'une seule source il y a la datatable Vols qui est alimentée à partir d'une base oracle la datatable recette qui est la synthèse de trois autres datatables Charter,Mslf,INTERLINE .
    la datatable charter est alimentée à partir d'une base oracle et les autres datatbles sont alimentées par deux fichiers dbf.
    L'utilisateur à la main de modifier le contenu de ces datatables avant l'exéction de la méthode recettecontrole() qui va affecter à chaque vol sa recette.
    Merci pour votre patience

  7. #7
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    quelque part, mes vieux souvenirs d'algo me feraient dire de chercher la :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //VOLSRow[] UncheckedVolsFoundsRows = (VOLSRow[])this.VOLS.Select("state=false");
    //foreach (VOLSRow MyVolRow in UncheckedVolsFoundsRows)
    //{
    //    MyVolRow.Status = false;
    //    MyVolRow.RowError = "Vol non trouvé dans Recette database";
    //}
    parce que deux boucles foreach imbriquee, en O(n2), ca peut faire mal, sur 4000 enregistrements

    D'autant qu'a premiere vue, l'ensemble VOLS peut etre modifie une fois que la recette a ete analysee-> on repart en O(n)

  8. #8
    Membre à l'essai
    Inscrit en
    Octobre 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 18
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par pvialatte Voir le message
    quelque part, mes vieux souvenirs d'algo me feraient dire de chercher la :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //VOLSRow[] UncheckedVolsFoundsRows = (VOLSRow[])this.VOLS.Select("state=false");
    //foreach (VOLSRow MyVolRow in UncheckedVolsFoundsRows)
    //{
    //    MyVolRow.Status = false;
    //    MyVolRow.RowError = "Vol non trouvé dans Recette database";
    //}
    parce que deux boucles foreach imbriquee, en O(n2), ca peut faire mal, sur 4000 enregistrements

    D'autant qu'a premiere vue, l'ensemble VOLS peut etre modifie une fois que la recette a ete analysee-> on repart en O(n)


    Cette boucle foreach n'est exécuter qu'après la fin de la première boucle.
    Et dans mes test j'ai bien enlevé cette boucle le temps de réponse est encore très très lent.

  9. #9
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    pffff...

    desole, c'est le resto de ce midi qui m'a perturbe la vision

    Par contre, dans le doute, passe un coup de profiler, au moins, ca te permettra de voir exactement quelle instruction te bouffe le plus de temps

  10. #10
    Membre à l'essai
    Inscrit en
    Octobre 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 18
    Points : 12
    Points
    12
    Par défaut
    quel outil me conseillez vous?

  11. #11
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465

  12. #12
    Membre à l'essai
    Inscrit en
    Octobre 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 18
    Points : 12
    Points
    12
    Par défaut
    j'ai passé ANTS profiler .
    j'ai pas su tirer profit de son rapport

  13. #13
    Membre à l'essai
    Inscrit en
    Octobre 2008
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 18
    Points : 12
    Points
    12
    Par défaut
    Enfin c'est résolu ,
    En fait beaucoups de contrôles sont liés à ces datatables.
    la solution est de simplement libérer les datasources des différents bindingsources liés à ces datatables [xxx]Bindingsource.datasource=null
    et de remettre le databinding après l'exécution de la méthode.
    le traitement ne prend désormais que deux minutes (7amdoulah).
    J'ai ajouté les deux Helpers suivant que je doit appeler l'une avant l'exécution du traitement et l'autre à sa fin.
    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
    private void DeconnectDataSources()
            {
                VolsFoundBindingSource.Sort = "";
                VolsBindingSource.DataSource = null;
                VolsFoundBindingSource.DataSource = null;
                RecetteBindingSource.Sort = "";
                RecetteBindingSource.DataSource = null;
                RecetteFoundsBindingSource.Sort = "";
                RecetteFoundsBindingSource.DataSource = null;
                Heure_DTextBox.DataBindings.Clear();
                Heure_DTextBox.DataBindings.Clear();
                Heure_RTextBox.DataBindings.Clear();
                Ville_DTextBox.DataBindings.Clear();
                Ville_RTextBox.DataBindings.Clear();
                FcTextBox.DataBindings.Clear();
                YcTextBox.DataBindings.Clear();
                BbTextBox.DataBindings.Clear();
                CompagnieTextBox.DataBindings.Clear();
                AffreteCheckBox.DataBindings.Clear();
                FictifCheckBox.DataBindings.Clear();
            }
            private void ConnectDataSource()
            {
                VolsBindingSource.DataSource = MyRecetteDataSet.VOLS;
                VolsFoundBindingSource.DataSource = VolsFoundsDataView;
                RecetteBindingSource.DataSource = MyRecetteDataSet.Recette;
                RecetteFoundsBindingSource.DataSource = RecetteFoundsDataView;
                Heure_DTextBox.DataBindings.Add("text", VolsBindingSource, "heure_d", true);
                Heure_RTextBox.DataBindings.Add("text", VolsBindingSource, "heure_r", true);
                Ville_DTextBox.DataBindings.Add("text", VolsBindingSource, "ville_d", true);
                Ville_RTextBox.DataBindings.Add("text", VolsBindingSource, "ville_r", true);
                FcTextBox.DataBindings.Add("text", VolsBindingSource, "fc", true);
                YcTextBox.DataBindings.Add("text", VolsBindingSource, "yc", true);
                BbTextBox.DataBindings.Add("text", VolsBindingSource, "bb", true);
                CompagnieTextBox.DataBindings.Add("text", VolsBindingSource, "compagnie", true);
                AffreteCheckBox.DataBindings.Add("Checked", VolsBindingSource, "affrete");
                FictifCheckBox.DataBindings.Add("Checked", VolsBindingSource, "fictif");
            }

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

Discussions similaires

  1. optimiser le code d'une fonction
    Par yanis97 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 15/07/2005, 08h41
  2. Optimiser mon code ASP/HTML
    Par ahage4x4 dans le forum ASP
    Réponses: 7
    Dernier message: 30/05/2005, 10h29
  3. optimiser le code
    Par bibi2607 dans le forum ASP
    Réponses: 3
    Dernier message: 03/02/2005, 14h30
  4. syntaxe et optimisation de codes
    Par elitol dans le forum Langage SQL
    Réponses: 18
    Dernier message: 12/08/2004, 11h54
  5. optimisation du code et var globales
    Par tigrou2405 dans le forum ASP
    Réponses: 2
    Dernier message: 23/01/2004, 10h59

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