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 :

Même les stations unix peuvent ramer!


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de crashtib
    Homme Profil pro
    Support technico-fonctionnel
    Inscrit en
    Avril 2009
    Messages
    221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Support technico-fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 221
    Par défaut Même les stations unix peuvent ramer!
    Salut à tous, j'ai une petite question concernant les performances d'un programme.

    Je m'explique :

    mon programme, pour l'instant, ne fait rien de plus que lancer une procédure nommée LireLigne, qui lit un nombre de lignes défini d'un document et renvoie un tableau de string.

    Jusqu'ici, c'est super, sauf que quand je le lance pour un fichier qui fait >10 millions de lignes, ça ralentit au fur et à mesure que les lignes sont lues! Donc je me suis dit "c'est à cause de la libération de mémoire que je n'ai pas faite".

    Et apparament je l'ai mal faite, puisque apparament ça ralentit toujours.


    Voici DecoderReseau, dites-lui bonjour et soyez gentil avec lui

    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
    void DecoderReseau()
    {
            char ** donnees;
            char temp[300];
            int i;
            int fini = 0;
            int lignedebut = 0;
            int lignefin = 1000;
            int compteur = 0;
     
     
            do
            {
                    donnees = LireLigne(CHEMINFICHIER_EXTRACTION_MPS, lignedebut, lignefin);
     
                    //traitement, decodage
     
     
     
                    lignedebut = lignefin;
                    lignefin += 1000;
     
     
                    printf("\nbloc %d\n", compteur);
                    compteur++;
     
     
                    //verification de fin de document et liberation memoire
                    for ( i = 0; i < 1000; i ++)
                    {
                            if ( !(strcmp(donnees[i], "#FIN")))fini++;
                            free(donnees[i]);
                            free(donnees);
                    }
            }while (!fini);
     
    }

    et voici LireLigne

    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
    char ** LireLigne(char* nomfichier, int lignedebut, int lignefin)
    {
            int i;
            FILE * fichier;
            char ** donnees = malloc(sizeof(char*)*(1+lignefin-lignedebut));
            char temp[512];
     
            if((fichier = fopen (nomfichier, "r"))!=NULL)
            {
     
                    for (i = 1; i < lignedebut ; i++)
                    {
                            if((fgets(temp, sizeof(temp), fichier))==NULL)break;
                    }
     
                    for (i = 0; i <= (lignefin-lignedebut) ; i++)
                    {
                            if((fgets(temp, sizeof(temp), fichier))!=NULL)
                            {
                                    donnees[i] = (char *)malloc(sizeof(char)*strlen(temp));
                                    strcpy(donnees[i], temp);
                            }
                            else
                            {
                                    donnees[i] = "#FIN";
                            }
                    }
     
                    fclose(fichier);
            }
            else
            {
                    printf("\nFichier introuvable\n");
            }
            return donnees;
     
    }

    pouvez-vous me dire ce que j'ai oublié?



    PS : pour les unixiens, connaissez-vous un moyen de réduire un fichier très gros sans l'ouvrir? j'ai que vi et le fichier est trop gros, je peux pas l'ouvrir

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void DecoderReseau()
    ....
                    for ( i = 0; i < 1000; i ++)
                    {
                            if ( !(strcmp(donnees[i], "#FIN")))fini++;
                            free(donnees[i]);
                            free(donnees);
                    }
    ....
    free(donnees) est fait bien trop tôt : il ne doit être fait qu'après la libération de toutes les donnees[i];
    Qu'est ce qui garantit que 1000, et exactement 1000, donnees[i] ont été allouées ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                    for ( i = 0; i < 1000; i ++)
                    {
                            if ( !(strcmp(donnees[i], "#FIN")))fini++;
                            free(donnees[i]);
                    }
                    free(donnees);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char ** LireLigne(char* nomfichier, int lignedebut, int lignefin)
    .....
                                    donnees[i] = (char *)malloc(sizeof(char)*strlen(temp));
                                    strcpy(donnees[i], temp);
    La zone allouée est trop faible : il n'y a pas la place du zéro terminal placé par strcpy:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char ** LireLigne(char* nomfichier, int lignedebut, int lignefin)
    .....
                                    donnees[i] = malloc(strlen(temp)+1);
                                    strcpy(donnees[i], temp);

  3. #3
    Membre confirmé Avatar de crashtib
    Homme Profil pro
    Support technico-fonctionnel
    Inscrit en
    Avril 2009
    Messages
    221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Support technico-fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 221
    Par défaut
    C'est exact et c'est bien vu. Néanmoins ça ralentit toujours

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Probablement, ceci est lié à l'allocation mémoire et/ou à la recopie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    donnees[i] = (char *)malloc(sizeof(char)*strlen(temp));
    strcpy(donnees[i], temp);
    Il faudrait le confirmer en essayant en supprimant les deux lignes et voir si le phénomène continue.

    Si c'est lié à ces lignes, il faudra modifier le code pour s'en débarrasser.

  5. #5
    Membre confirmé Avatar de crashtib
    Homme Profil pro
    Support technico-fonctionnel
    Inscrit en
    Avril 2009
    Messages
    221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Support technico-fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 221
    Par défaut
    en l'occurence je ne peux pas trop me passer de cette architecture (j'ai une dizaine de .c qui sont construits pour utiliser lireligne).

    De plus, ce ne sont pas les deux lignes dont tu parles qui sont incriminées. Je n'ai vraiment aucune idée de ce que cela pourrait être. Ce n'est pas leur faute puisque lorsque je les mets en commentaire et les free en commentaire aussi, ça fait pareil et ça relentit tout autant.

    je vais essayer de faire des tests autre part, mais je pars la mort dans l'âme... ça me scie en deux de savoir que je perds une après-midi sur un détail comme ça.

  6. #6
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Dans la fonction LireLigne cette boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                    for (i = 1; i < lignedebut ; i++)
                    {
                            if((fgets(temp, sizeof(temp), fichier))==NULL)break;
                    }
    va être de plus en plus longue à exécuter car lignedebut est de plus en plus grand au fur et à mesure que tu avance dans l'exécution de ton prog.

Discussions similaires

  1. Verrou empechant même les select
    Par ilalaina dans le forum Administration
    Réponses: 11
    Dernier message: 03/10/2007, 15h55
  2. Réponses: 3
    Dernier message: 16/06/2007, 19h47
  3. Réponses: 9
    Dernier message: 14/06/2007, 12h22
  4. Réponses: 2
    Dernier message: 16/12/2006, 19h00

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