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 :

Optimisation de scripts Perl


Sujet :

Langage Perl

  1. #1
    Membre actif Avatar de Fango
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 197
    Points : 205
    Points
    205
    Par défaut Optimisation de scripts Perl
    Bonjour a tous,

    j'ai un script qui tourne sur une trentaine de Go de fichiers de logs dans le but d'etablir des stats. Il prend chaque fichier, le lit ligne par ligne, cherche quelques patterns, construit 2 gigantesques hash maps (et une localisee par fichier), et log dans un fichier de resultat. Il marche tres bien mais a priori il va tourner pendant une bonne dizaine de jours...

    Auriez vous des recommandations pour essayer d'optimiser le temps d' execution ?

    Merci.

  2. #2
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Bah avoir des fichiers plus petit . Sérieusement, si ton script est long, bah c'est qu'il y a beaucoup de données à gérer, donc je ne vois pas comment tu pourrais faire autrement. Est ce un script qui tournera en boucle ? Pourquoi utiliser les hashmap ? Sans script, difficile de se faire une idée ?

  3. #3
    Membre actif Avatar de Fango
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 197
    Points : 205
    Points
    205
    Par défaut
    Hello,

    merci de ta reponse. Je pense que la limitation viens des hash map... C'est un script qui prend tous les fichiers d' un repertoire, verifie que le nom correspond a un pattern et les lit ligne par ligne. Il recherche une ligne (une seul expression reguliere) dans chaque fichier et update une hash map qui tient a jour le nombre de lignes differentes globalement en gros et une autre qui le fait par tranche horaire. Ca donne a peu pres ca :

    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
    my %hash = ();
    my %hash_time = ();
    my @update_list = ();
     
    Foreach file
      if (file =~ /pattern/) {
        &Extract();
      }
     
      // iterate on the hash maps and compute stats
     
    #-----------------------------
    sub Extract
    {
      open (IN, <file);
      while ($line=<IN>)
      {
        if (line =~ /pattern/){
          my @res_list=grep ( { $_ eq $update } @update_list);
          if (@res_list > 0){
            $hash{$update}++;
          }else{   # Not in the list
             $update_list[@update_list] = $update;
    	  # Init
              $hash{$update}=1;
      	  $hash_time{$time_key}++;
          }
        }
      }
      close IN;
    }
    J' ai l'impression que je ne peux pas optimiser grand chose et que la limitation vient de Perl J' ai deja enlever le process d' ecrire des logs dans un fichier, mais ca n'a pas vraiment eu d' impact sur les perfs

  4. #4
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    euh, ton code perl est un peu bizarre car il y a des syntaxes pas très bien écrites. De plus, je ne vois pas l'intérêt des hashmap, pourquoi ne pas mettre tes résultats dans un fichier (avec >>) à la suite.

  5. #5
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Combien de CPU/coeurs possède ta machine?

    si elle en a plusieurs il pourrait être intéressant de multi-threader ton script.



    si le fichiers sont neombreux et petit j'aurais plutôt fait ceci pour directement avoir les lignes qui m'intéressent dans le fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    open FILE, "<", "file" or die $!
    my @selectedLines = grep (/pattern/,<FILE>);
    close FILE
     
    ## traitement sur @seledtedLines pour avoir la hashmap
    là ou je suis je n'ai pas perl sour la main mais l'esprit et là je pense.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  6. #6
    Membre actif Avatar de Fango
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 197
    Points : 205
    Points
    205
    Par défaut
    Citation Envoyé par djibril Voir le message
    euh, ton code perl est un peu bizarre car il y a des syntaxes pas très bien écrites. De plus, je ne vois pas l'intérêt des hashmap, pourquoi ne pas mettre tes résultats dans un fichier (avec >>) à la suite.
    Oui, je l'ai ecrit en "pseudo Perl" pour aller plus vite et faire en sorte que le code ne soit pas long.
    Les hash maps, c'est pour associer un update (chaine de caractere dans la ligne que je recherche dans les fichiers) a son nombre d'occurences dans tous les fichiers du repertoire.

    Citation Envoyé par jabbounet Voir le message
    Combien de CPU/coeurs possède ta machine?

    si elle en a plusieurs il pourrait être intéressant de multi-threader ton script.



    si le fichiers sont neombreux et petit j'aurais plutôt fait ceci pour directement avoir les lignes qui m'intéressent dans le fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    open FILE, "<", "file" or die $!
    my @selectedLines = grep (/pattern/,<FILE>);
    close FILE
     
    ## traitement sur @seledtedLines pour avoir la hashmap
    là ou je suis je n'ai pas perl sour la main mais l'esprit et là je pense.
    Je lance ce script sur un serveur Linux. J'ai fait cat /proc/cpuinfo et apparemment il y a 4 processeurs Le probleme avec le multi-thread, c'est que je ne veux pas traiter chaque fichier dans leur coin, mais en connaissant les updates qui ont deja ete faits dans les autres fichiers deja traites. Je ne connais pas les threads en perl mais je ne pense pas que ca s' appliquerait dans le cas present.
    Je vais essayer avec le bout de code que tu m' as file, meme si les fichiers sont gros, ca ameliorera peut etre les perfs ! Quelle est la difference par rapport a une expression reguliere ? C' est vraiment plus efficace ?

  7. #7
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    pour les threads


    http://perldoc.perl.org/perlthrtut.h...-Perl-threads?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    use threads;
     
    my $thr = threads->create(\&sub1);
     
    sub sub1 {
    print("In the thread\n");
     
    }
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  8. #8
    Membre actif

    Profil pro
    Inscrit en
    Août 2009
    Messages
    156
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 156
    Points : 211
    Points
    211
    Par défaut
    Ca sera plus efficace car tu ouvriras moins de ligne sur le fichier dans ton script Perl.
    Après tu vas quand même boucler sur tout le fichier pour trouver tes occurences, mais grep doit être plus optimisé qu'un parcours systématique de tout le fichier par un while.

    Avant toute chose, je testarais comme suit:
    - juste boucler sur tes fichiers, en ne fesant que le parcours et aucun traitement (une fois avec ta méthode initiale, une fois avec la methode qui greppe directement)
    - ensuite refaire le même en faisant tes traitements

    Tu verras déjà où le temps est passé, et s'il faut travailler sur l'ouverture et le parcours des fichiers ou si tes traitements sont aussi à optimiser.

    Dans tous les cas selon ta machine, parser des gigas de log prendra forcément du temps. :-( Pour éventuellement gagner encore plus, ptêt un programme C compilé sera plus rapide, mais je ne pense pas que tu gagnes beaucoup car le progrmma Perl ne doit être compilé en langage machine qu'une fois, pas à chaque ligne -à vérifier ou infirmer-

  9. #9
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par 50Nio Voir le message
    Ca sera plus efficace car tu ouvriras moins de ligne
    Dans tous les cas selon ta machine, parser des gigas de log prendra forcément du temps. :-( Pour éventuellement gagner encore plus, ptêt un programme C compilé sera plus rapide, mais je ne pense pas que tu gagnes beaucoup car le progrmma Perl ne doit être compilé en langage machine qu'une fois, pas à chaque ligne -à vérifier ou infirmer-
    Perl est un langage de script moderne, le script est "compilé" au moment ou tu le lance le script et ensuite c'est que du binaire ou du pseudo code.


    Je lance ce script sur un serveur Linux. J'ai fait cat /proc/cpuinfo et apparemment il y a 4 processeurs Le probleme avec le multi-thread, c'est que je ne veux pas traiter chaque fichier dans leur coin, mais en connaissant les updates qui ont deja ete faits dans les autres fichiers deja traites. Je ne connais pas les threads en perl mais je ne pense pas que ca s' appliquerait dans le cas present.
    tu as donc une section critique ici.


    Après ne connaissant pas la finalité exacte de ton script, quelques exemple de fichier d'entrées et de sortie serait bienvenue, ton problème peu peu être se résoudre de façon plus simple ou plus complexe.
    http://www.perlmonks.org/?node_id=597051
    http://www.perl.com/pub/a/2004/08/09...ne.html?page=2
    http://stackoverflow.com/questions/8...ns-on-the-same
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  10. #10
    Membre actif Avatar de Fango
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 197
    Points : 205
    Points
    205
    Par défaut
    Merci ! J'ai utilisé toutes vos recommendations, mais c'etait encore le remplissage des hash maps qui posaient pb. Du coup, j'ai migré ce code dans un petit programme c++ (sans chercher a l'optimiser particulierement) en adaptant le script perl. Et la, je suis passe de 40 minutes a 4 secondes de process en testant sur 10 fichiers de log a parser...

    Encore merci en tout cas, maintenant j'ai un super script multi threadé interfacé avec un binaire c++... aucun rapport avec mon script initial Et c'etait vraiment interessant de tester les threads en perl.

  11. #11
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    mouais, je reste persuadé que c'est ton algo en perl qui pose souci, car passer de 40 min à 4 sec juste en changeant de langage de programmation, je trouve ça bizarre. Mais, bon, tant mieux si tu arrives à faire ce que tu veux.

  12. #12
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    oui ça fait pas mal de différence en temps ça ne devrais pas être aussi grand.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  13. #13
    Membre actif Avatar de Fango
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 197
    Points : 205
    Points
    205
    Par défaut
    Citation Envoyé par djibril Voir le message
    mouais, je reste persuadé que c'est ton algo en perl qui pose souci, car passer de 40 min à 4 sec juste en changeant de langage de programmation, je trouve ça bizarre. Mais, bon, tant mieux si tu arrives à faire ce que tu veux.
    Non, l'algo est celui que je vous ai decrit, mi plus ni moins. Je gerais 2 hash maps dont les cles etaient de petites chaines de caracteres et les valeurs des nombres, qui etaient updates tres souvent, sur un gros volume de donnees.

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

Discussions similaires

  1. optimisation script perl
    Par vince2005 dans le forum Langage
    Réponses: 4
    Dernier message: 22/09/2010, 13h53
  2. Optimisation des perfs d'un script perl
    Par photorelief dans le forum Langage
    Réponses: 7
    Dernier message: 12/11/2009, 09h37
  3. [langage] awk et sed dans script perl
    Par scoti dans le forum Langage
    Réponses: 3
    Dernier message: 07/04/2003, 18h26
  4. Réponses: 2
    Dernier message: 11/07/2002, 08h31

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