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 :

Performance de substring sur un très grand nombre de ligne ?


Sujet :

C#

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 104
    Points : 80
    Points
    80
    Par défaut Performance de substring sur un très grand nombre de ligne ?
    Bonjour,

    Je dois effectue un nombre conséquent d'extractions de caractères pour chaque ligne lue dans un fichier relativement gros (260 000 lignes mais qui pourra attendre à l'avenir facilement 10 fois plus).

    La lecture du fichier et le stockage dans une list sont instantannés (inférieur à la seconde).

    Par contre le traitement de chaque ligne de cette list est beaucoup plus longue.

    tout d'abord le 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
     
    private void ecritureFichierSortie()
            {
                foreach (string ligne in fichier_vecteur)
                {
                    fichierSortie.WriteLine(SplitAndSave(ligne));
                }
            }
     
    private string SplitAndSave(string line)
            {
                // on récupère le code
                string code = line.Substring(debutChampsIdentifiant, tailleChampsIdentifiant);
                // on parcours les matrice de décodage et on enregistre dans le fichier de sortie
                string ligneSortie = string.Empty;
                foreach (LigneMatriceDecodage ligne in matrideDeDecodage)
                {
                    if (String.Compare(code, ligne._code) == 0)
                    {
                        try
                        {
                            ligneSortie += line.Substring(ligne._debut, ligne._taille) + ";";
                        }
                        catch (Exception e)
                        {
                            ligneSortie += string.Empty + ";";
                        }
                    }
                    else
                    {
                        ligneSortie += string.Empty + ";";
                    }
                }
                return ligneSortie;
            }
    la variable "fichier_vecteur" contient une list<String> donc l'ensemble de mon fichier en entrée.
    En mettant en commentaire la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ligneSortie += line.Substring(ligne._debut, ligne._taille) + ";";
    de la fonction splitAndSave le traitement est ultra rapide. De même en le remplaçant par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ligneSortie += ";"
    le traitement ne dure que 3 secondes.

    en utilisant mon substring la durée du traitement s'envole à 16minutes.

    Il est donc évident que c'est l'extraction des données via substring qui pose problème.
    Je me demande donc si il existe une autre méthode/fonction nécessitant moins de temps de calcul pour récupérer mes données dans ce String (sachant qu'à la base je n'ai pas de délimiteur dans le fichier et que j'utilise donc une description du fichier pour faire mon découpage pour chaque ligne. Sachant aussi que la structure de la ligne dépend d'un code enregistrement qui se situe à la 25ème colonne de cette ligne ).

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Bonjour

    Attention : le fait de travailler dans un bloc try/catch dégrade sensiblement les perf.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  3. #3
    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

    ceci C'est l'horreur egalement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ligneSortie += line.Substring(ligne._debut, ligne._taille) + ";";
    Utilise plutot un stringbuilder

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    StringBuilder ligneSortie=new StringBuilder();
    ligneSortie.Append(line,ligne._debut, ligne._taille);
    ligneSortie.Append(";");
    « Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 104
    Points : 80
    Points
    80
    Par défaut
    Bluedeep :
    en effet le try catch était responsable de la dégradation du traitement (du coup maintenant il me faut que 3sec au lieu de 16 min )

    olibara :
    merci pour l'indice sur le stringbuilder. je n'avais jamais utilisé cette classe mais elle m'a l'air très intéressante (par contre je n'ai pas vu de différence en terme de performance mais il doit surement en avoir sur des fichiers de plusieurs centaines de méga par contre --> à tester prochainement !)

  5. #5
    Membre averti
    Homme Profil pro
    Développeur
    Inscrit en
    Septembre 2007
    Messages
    497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 497
    Points : 330
    Points
    330
    Par défaut
    Citation Envoyé par Bluedeep Voir le message
    Bonjour

    Attention : le fait de travailler dans un bloc try/catch dégrade sensiblement les perf.
    Par quoi remplacez vous le try catch du coup pour gerer les erreurs.
    (Dans le projet la d'ailleurs une verif aurait peut etre pu etre fait sans try catch et pour la gestion d'erreur encapsuler le foreach dans le try catch et non l'inverse pour ameliorer les perfs).

  6. #6
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Pour quantifier un peu le problème de perf. de skerdreux, j'ai lancé pendant que je bouffais le bout de code suivant :

    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
     
    List<string> myStrings = newList<string>();
    for (int i = 0; i < 100000; i++)
    {
    string myString = newstring((char)((i % 26) + 64), 50);
    myStrings.Add(myString);
    }
    DateTime begin1 = DateTime.Now;
    String final = string.Empty;
    foreach (string s in myStrings)
    {
    final += s.Substring(10, 20);
    }
    DateTime begin2 = DateTime.Now;
    String final2 = string.Empty;
    foreach (string s in myStrings)
    {
    try
    {
    final2 += s.Substring(10, 20);
    }
    catch
    {
    final2 += ";";
    }
    }
    DateTime begin3 = DateTime.Now;
    StringBuilder sbFinal = newStringBuilder();
    foreach (string s in myStrings)
    {
    sbFinal.Append(s.Substring(10, 20));
    }
    string final3 = sbFinal.ToString();
    DateTime begin4 = DateTime.Now;
    StringBuilder sbFinal2 = newStringBuilder();
    foreach (string s in myStrings)
    {
    try
    {
    sbFinal2.Append(s.Substring(10, 20));
    }
    catch
    {
    sbFinal2.Append(";");
    }
    }
    string final4 = sbFinal2.ToString();
    DateTime begin5 = DateTime.Now;
    Console.WriteLine("Temps 1 (concat) : {0} msec.", (begin2 - begin1).TotalMilliseconds);
    Console.WriteLine("Temps 2 (concat + try/catch) : {0} msec.", (begin3 - begin2).TotalMilliseconds);
    Console.WriteLine("Temps 3 (strinbuilder) : {0} msec.", (begin4 - begin3).TotalMilliseconds);
    Console.WriteLine("Temps 4 (strinbuilder + try/catch): {0} msec.", (begin5 - begin4).TotalMilliseconds);
    Console.ReadKey();
    
    Voici le résultat :
    Temps 1 (concat) : 371776,8225 msec.
    Temps 2 (concat + try/catch) : 367962,9275 msec.
    Temps 3 (strinbuilder) : 31,2632 msec.
    Temps 4 (strinbuilder + try/catch): 15,6316 msec.

    Ca appelle deux commentaires :

    - le try/catch ne dégrade pas les perfs (je pensais le contraire).
    - le concaténation de chaine dégrade enoooooooormément les perfs (ça je le savais, mais pas à ce point).

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 104
    Points : 80
    Points
    80
    Par défaut
    Pour être plus précis sur mon problême avec le try catch c'est que à chaque ligne il rentrait dans le try catch ce qui exemple le temps de calcul en plus.
    (les fichiers MAJIC ne sont pas un exemple de fichier bien structuré !).

    ensuite je pense que pour voir la différence il faudrait plus de lignes et plus de concaténations mais dans tous les cas c'est bon à retenir qu'il vaut mieux utiliser le stringbuilder !

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

Discussions similaires

  1. [MySQL] SELECT, INSERT et UPDATE sur un très grand nombre de lignes pour faire un classement
    Par sagat06 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 01/04/2014, 18h52
  2. Réponses: 4
    Dernier message: 14/11/2012, 12h14
  3. Recherche intra-site sur un très grand nombre de fichiers
    Par Poumpay dans le forum Général Conception Web
    Réponses: 5
    Dernier message: 13/07/2010, 21h32
  4. Trés grand nombre
    Par rteuteu55 dans le forum C++Builder
    Réponses: 10
    Dernier message: 15/11/2005, 11h28
  5. Une unité pour gérer des très grands nombres
    Par M.Dlb dans le forum Langage
    Réponses: 2
    Dernier message: 09/09/2003, 12h07

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