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

Langage Perl Discussion :

PB de performance de lecture d'un fichier :


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 51
    Par défaut PB de performance de lecture d'un fichier :
    Bonjour,

    Je débute en perl et j'ai un problème de performance. Je reçois des trés gros fichiers qui peuvent dépasser 2,5 Giga octet. J'ai un traitement qui concatène des lignes de ce fichier à l'aide d'une clé qui est devant toutes lignes.

    Lorsque je dépasse des fichiers de taille 1,8 Giga Octet, le programme ne fonctionne plus.

    Je soupçonne que c'est la lecture du fichier amont qui ne fonctionne plus. Car il n'écrit jamais dans le fichier de sortie.

    Voici le code de lecture du fichier initial :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # chargement du fichier en entrée:
    open(IN, "$FIC_PARAM") || die "Erreur E/S:$!\n";
    my @CONTENU = <IN>;
    close(IN);

    Pour les performances, quelles sont les autres méthodes de stockage de fichier?

    Merci d'avance

  2. #2
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Citation Envoyé par ksper45 Voir le message
    Je débute en perl et j'ai un problème de performance. Je reçois des trés gros fichiers qui peuvent dépasser 2,5 Giga octet. J'ai un traitement qui concatène des lignes de ce fichier à l'aide d'une clé qui est devant toutes lignes.
    Ce n'est pas clair, que fais tu avec ce fichier ?

    Citation Envoyé par ksper45 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # chargement du fichier en entrée:
    open(IN, "$FIC_PARAM") || die "Erreur E/S:$!\n";
    my @CONTENU = <IN>;
    close(IN);
    Ben forcément... Si tu mets l'intégralité du fichier en mémoire alors qu'il fait dans les 2.5 Go, tu fais du mal à ta RAM.
    La bonne solution est de traiter le fichier séquentiellement, ne gardant qu'une (ou quelques unes) ligne à la fois en mémoire. Si tu ne peux pas traiter ce fichier séquentiellement ou au moins par morceau, c'est une erreur de design, tu devrais probablement être en train d'utiliser une base de données.

    --
    Jedaï

  3. #3
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 51
    Par défaut
    En fait, je concatène les lignes du fichier.

    Voici un exemple simplifié du fichier d'entrée :

    2008-08-22-23.00.27.24567100001Hello
    2008-08-22-23.00.27.24567100002the
    2008-08-22-23.00.27.24567100003world

    J'ai une clé identique qui change juste a la fin avec le numéro de ligne.

    Le résiultat final, je veux juste Hello the world.

    J'ai énormément de données par moment et je souhaite tout traiter.

    Comment pourrais je le traiter séquentiellement?

    Voici mon code en entier :

    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    #####################definition des variables#########################################
    my $FIC_PARAM;
    my $FIC_RES_PMART;
    my $IFS_OLD;
    my $IFS;
    my $CLE;
    my $CLE_OLD;
    my $P_XML;
    my $LG_LIGNE;
    my $LG_CLE;
    my $AFF_CLE;
     
    $FIC_PARAM ="$ENV{IN_CHAINE}/RTFPRV.dat";
    $FIC_RES_PMART ="$ENV{SRC}/trafic_pvol.xml";
     
     
    #--------------- Test existence du fichier initial -------------
    #--- FIC_PARAM ---
     
     
    #suppression des fichiers resultats
    unlink ("$FIC_RES_PMART");
     
    ###### modification de la variable IFS
    $IFS_OLD=$IFS;
    $IFS="
    ";
     
     
    # chargement du fichier en entrée:
    open(IN, "$FIC_PARAM") || die "Erreur E/S:$!\n";
    my @CONTENU = <IN>;
    close(IN);
     
     
     
    # ouverture du fichier en sortie
    open(OUT, ">$FIC_RES_PMART") || die "Erreur E/S:$!\n";
     
    # insertion de la premiuere ligne dans le fichier de sortie
    print OUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    print OUT "<List_Ass xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"file:ass.xsd\">";
     
    my $ITERATION = 1;
     
    # pour chaque ligne du fichier 
    foreach my $LIGNE (@CONTENU) 
    {
        chomp $LIGNE;
        # si on est sur la première ligne on conserve juste la clé
        if ($ITERATION == 1)
        {
        	# récupération de la clé
        	$CLE_OLD=substr($LIGNE, 2, 26);
        	$ITERATION = 0;
        }
        else
        {
        	# récupération de la clé
        	$CLE=substr($LIGNE, 2, 26);
     
       		# si la reference de la ligne est egal a la derniere reference
       		if ($CLE eq $CLE_OLD)
       		{
       			# récupère la longueur de la ligne
       			$LG_LIGNE=length($LIGNE);
     
       			$P_XML=substr($LIGNE, 46, $LG_LIGNE);
       			# supprime les blanc en fin de ligne
       			$P_XML=~s/\s+$//g;
       			print OUT "$P_XML";
       		}
       		else
       		{
       			# insertion d un retour chariot puis de la partie xml de la ligne
            # récupère la longueur de la ligne
       			$LG_LIGNE=length($LIGNE);
       			$LG_CLE=length($CLE);
     
            $P_XML=substr($LIGNE, 51, $LG_LIGNE);
     
            if ("$CLE" ne "0000-00-00-00.00.00.000000" and "$CLE" ne "9999-99-99-99.99.99.999999")
            {
            	# récupération d'une partie de la clé
            	$AFF_CLE=substr($CLE, 3, $LG_CLE);
     
            	# insertion de cle dans les Message
            	print OUT "\n";
            	print OUT "<Ass><Cle_Mess>";
            	print OUT "$CLE";
            	print OUT "</Cle_Mess>";
     
            	# insertion du debut du message
            	print OUT "$P_XML";
     
            }
           }
           # la derniere reference devient la reference de la ligne courante
    			 $CLE_OLD=$CLE;
    		 }
     
     
    }
    print OUT "\n</List_Ass>";
     
    # fermeture fichier résultat
    close(OUT);

    Ce programme fonctionne trés bien avec des fichiers d'1.8 Giga

    Merci d'avance pour votre aide.

  4. #4
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    En bref tu traites déjà ton fichier complètement séquentiellement mais tu charges tout de même l'intégralité du fichier en mémoire avant de commencer le traitement....

    Lis donc notre FAQ pour un minimum sur la lecture de fichier ligne par ligne.

    --
    Jedaï

  5. #5
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 51
    Par défaut
    Citation Envoyé par Jedai Voir le message
    En bref tu traites déjà ton fichier complètement séquentiellement mais tu charges tout de même l'intégralité du fichier en mémoire avant de commencer le traitement....

    Lis donc notre FAQ pour un minimum sur la lecture de fichier ligne par ligne.

    --
    Jedaï
    Merci maitre (Jedai)..... Je regardes et si j'ai des questions... je reviens

  6. #6
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 51
    Par défaut
    Merci!
    Le programme est optimisé...

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

Discussions similaires

  1. Performances en lecture d'un fichier (std::getline)
    Par TheSeb dans le forum SL & STL
    Réponses: 29
    Dernier message: 13/07/2012, 00h16
  2. Comment mesurer les performances des I/O (lecture d'un fichier XML)?
    Par LGnord dans le forum Tests et Performance
    Réponses: 2
    Dernier message: 08/11/2011, 11h39
  3. Performance lors de la lecture d'un fichier excel
    Par Acarp47 dans le forum VBA Access
    Réponses: 3
    Dernier message: 29/08/2007, 19h18
  4. [performance] Lecture d'un fichier
    Par Ceylo dans le forum C
    Réponses: 13
    Dernier message: 30/01/2007, 16h07
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 10h24

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