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 :

Diminuer le temps d'execution d'un script perl


Sujet :

Langage Perl

  1. #1
    Membre régulier
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Points : 81
    Points
    81
    Par défaut Diminuer le temps d'execution d'un script perl
    Bonjour à tous,

    J'ai écris un script perl, qui prend en entrée un fichier de cette forme :

    ATGCGTAGC 12
    GTCTAGCATGA 1
    ATGCGTAGC 15
    TGATGGGTAC 12

    et qui me donne en fichier de sortie :

    >dme_pi_1_9_27
    ATGCGTAGC
    >dme_pi_2_11_1
    GTCTAGCATGA
    >dme_pi_3_10_12
    TGATGGGTAC

    soit :
    >dme_pi_nombrequelconque_nombredelettre_somme2écolonne

    Voici le script :

    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
    #!/usr/bin/perl
    use strict;
    use warnings;
    use Carp qw(confess);
    use Getopt::Long;
    use List::Util qw(sum);
     
    # supprime les pi en double,et leur assigne un identifiant unique 
    # format de sortie : .fasta
    # command line : perl create_bank_pi.pl --file banque_embryon_02h.txt > .fasta
     
    my $AF_class;
    my %hash;
    my $i=0;
     
    GetOptions("file=s" => \$AF_class);
    open(my $fh,'<',$AF_class) or die "$AF_class : $!\n\n";
    while (<$fh>){
    	if (/^[ATGC]/){
    		chomp;
    		my ($seq,$count) = split /\s+/,$_;
    		my $length = length($seq);
    		#$hash{$seq}++;
    		push(@{$hash{$seq}->{'count'}},$count);
    	}
     
     
    }
     
    foreach my $ID (keys(%hash)) {
    	#print ("ID=$ID\tcount=\t".join("\t", @{$hash{$ID}->{'count'}})."\n");
    	my $length = length($ID);
    	my $somme = sum(@{$hash{$ID}->{'count'}});
    	print ">dme_pi_".$i."_".$length."_".$somme."\n".$ID."\n";
    	$i++;
     
     
    }
     
    close($fh);
    Seulement, il est très très long à me donner une sortie, je voudrais donc savoir comment "otpimiser mon script , de façon à ce que quand je lui fourni un fichier d'entrée avec beaucoup de ligne, il ne soit pas aussi long à me retourner un résultat ...
    Merci d'avance.

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je ne comprends pas, chez moi, le résultat est instantané sur l'exemple donné.

  3. #3
    Membre régulier
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Points : 81
    Points
    81
    Par défaut
    oui et c'est bien cela mon problème,
    Sur l'exemple donné, mon script tourne très bien, mais sur mon fichier de 3 millions de lignes, cela fait 3h que mon script tourne et pas de réponse .... donc je me suis dit que j'avais fait des "étapes" qui prennent du temps ....

  4. #4
    Membre averti

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 184
    Points : 322
    Points
    322
    Par défaut
    C'est bien souvent les expressions régulières qui sont responsables.
    Tu devrais essayer en utilisant des tests basiques : tu prends la première lettre de la ligne et tu la compares avec les autres lettres.
    Du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my $c = substr $lines, 0, 1;
    if ( $c eq 'A' OR $c eq 'T' OR $c eq 'G' ) {
    }

  5. #5
    Membre régulier
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Points : 81
    Points
    81
    Par défaut
    j'ai mit cela car en fait j'ai concaténé des fichiers et j'ai dans le fichier :

    #blablabla
    #blablabla

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je doute fort que ce soit l'expression régulière "triviale" qui prenne du temps.
    Pourrais-tu mettre un say (ou un print/warn) après la fin de la lecture du fichier (le while), juste avant le traitement du tableau.
    Je pense que ton pb vient :
    - soit des calculs de sommes
    - soit de la gestion de la mémoire (trop de demande en RAM).

    Les lignes de ton énorme fichier d'entrée sont-elles toutes aussi courtes que celles données en exemple ?
    Pour nous permettre de profiler, pourrais-tu fournir un exemple de fichier très gros ?

  7. #7
    Membre régulier
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Points : 81
    Points
    81
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Pourrais-tu mettre un say (ou un print/warn) après la fin de la lecture du fichier (le while), juste avant le traitement du tableau.
    Je ne suis pas sure d'avoir bien compris :
    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
    #!/usr/bin/perl
    use strict;
    use warnings;
    use Carp qw(confess);
    use Getopt::Long;
    use List::Util qw(sum);
     
    # supprime les pi en double,et leur assigne un identifiant unique 
    # format de sortie : .fasta
    # command line : perl create_bank_pi.pl --file banque_embryon_02h.txt > .fasta
     
    my $AF_class;
    my %hash;
    my $i=0;
     
    GetOptions("file=s" => \$AF_class);
    open(my $fh,'<',$AF_class) or die "$AF_class : $!\n\n";
    while (<$fh>){
    	if (/^[ATGC]/){
    		chomp;
    		my ($seq,$count) = split /\s+/,$_;
    		my $length = length($seq);
    		#$hash{$seq}++;
    		push(@{$hash{$seq}->{'count'}},$count);
    	}
     
     
     
    }
     
    print "Bonjour\n";
     
    foreach my $ID (keys(%hash)) {
    	print ("ID=$ID\tcount=\t".join("\t", @{$hash{$ID}->{'count'}})."\n");
    	my $length = length($ID);
    	my $somme = sum(@{$hash{$ID}->{'count'}});
    	print ">dme_pi_".$i."_".$length."_".$somme."\n".$ID."\n";
    	$i++;
     
     
    }
     
    close($fh);

    Citation Envoyé par Philou67430 Voir le message
    Les lignes de ton énorme fichier d'entrée sont-elles toutes aussi courtes que celles données en exemple ?
    Les lignes de mon fichiers peuvent aller jusqu’à 50 lettres

    Citation Envoyé par Philou67430 Voir le message
    Pour nous permettre de profiler, pourrais-tu fournir un exemple de fichier très gros ?
    Je n'arrive pas à mettre de pièce jointe, j'ai le message d'erreur "Votre envoi ne peut pas être exécuté car la marque de sécurité est manquante." J'ai deposé un fichier à l'adresse suivante : http://filez.univmed.fr/download.php?ad=78697VwOPw

  8. #8
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Citation Envoyé par Isabella83 Voir le message
    Je ne suis pas sure d'avoir bien compris
    Tu as bien compris. Et quel est le résultat ? Le bonjour apparait vite ou lentement ? (permet d'identifier si la lenteur vient de la première partie du script, ou de la deuxième).

  9. #9
    Membre régulier
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Points : 81
    Points
    81
    Par défaut
    Non, il est long à s'afficher ... le "problème" vient donc de la première partie ....

  10. #10
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Il peut aussi venir des deux
    Mais ça donne déjà une indication de où regarder en premier.

  11. #11
    Membre régulier
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Points : 81
    Points
    81
    Par défaut
    Oui c'est sure, mais comment puis je faire en sorte que la boucle while soit moins longue en terme d’exécution ? cela pourrait il venir de la condition if ?

  12. #12
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je vais prendre quelques minutes pour regarder

  13. #13
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    J'ai utilisé Benchmark, et je mets 24s pour la partie "chargement du fichier", et 3 fois plus pour la partie "écriture fasta".

    Dans tous les cas, le traitement n'est pas démesuré en temps. De combien de mémoire dispose ta machine ?

    Le script tel que je l'ai modifié:
    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
    #!/usr/bin/perl
    use strict;
    use warnings;
    use Carp qw(confess);
    use Getopt::Long;
    use List::Util qw(sum);
    use Benchmark;
     
    # supprime les pi en double,et leur assigne un identifiant unique 
    # format de sortie : .fasta
    # command line : perl create_bank_pi.pl --in banque_embryon_02h.txt --out fasta.txt
     
    my ($AF_class, $AF_out);
    my %hash;
    my $i=0;
     
    GetOptions("in=s" => \$AF_class, "out=s" => \$AF_out);
    open(my $fh,'<',$AF_class) or die "$AF_class : $!\n\n";
    open(my $fh_out,'>',$AF_out) or die "$AF_out : $!\n\n";
     
    sub load() {
      while (<$fh>){
        if (/^[ATGC]/){
          chomp;
          my ($seq,$count) = split /\s+/,$_;
          my $length = length($seq);
          #$hash{$seq}++;
          push(@{$hash{$seq}->{'count'}},$count);
        }
      }
    }
     
    timethis(1, \&load, "Load bank");
     
    sub save() {
      foreach my $ID (keys(%hash)) {
        #print ("ID=$ID\tcount=\t".join("\t", @{$hash{$ID}->{'count'}})."\n");
        my $length = length($ID);
        my $somme = sum(@{$hash{$ID}->{'count'}});
        print { $fh_out } ">dme_pi_".$i."_".$length."_".$somme."\n".$ID."\n";
        $i++;
      }
    }
     
    timethis(1, \&save, , "Save fasta");
     
    close($fh);
    close($fh_out);
    (pas de modif de l'algorithme de traitement : j'ai juste ajouté un argument pour le fichier de sortie, mis sous forme de fonction les deux parties du traitement et appelé les fonctions de calcul de temps pour le Benchmark).

  14. #14
    Membre régulier
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Points : 81
    Points
    81
    Par défaut
    8 GO de RAM mais je suis sous virtualbox pour linux ... cela vient peut etre de ca ?
    Car j'ai laissé tourner 3h et je n'ai eu aucun résultat ...

  15. #15
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Combien as-tu attribué de RAM à ta machine virtuelle Linux ?
    Avec 8Go sous Windows, ça devrait tourner vite. J'ai fait tourner ton exemple sous Windows XP, 2Gà de RAM, et pleins d'applications qui tournent en parallèle.
    Je fais tourner le perl sous Cygwin, version perl 5.14.1.

  16. #16
    Membre régulier
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Points : 81
    Points
    81
    Par défaut
    c'est un informaticien qui l'a fait , je crois qu'il m'a mit 500Mo le max étant 1024 il me semble ...

  17. #17
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    OK... laisse tomber donc !
    D'abord, il n'y a pas de limite hormis la mémoire physique (et une marge pour laisser tourner le système hôte) : tu peux donc modifier la configuration et mettre 2Go (tu dois d'abord éteindre ta machine virtuelle).

    Autre solution : faire installer cygwin et travailler directement depuis Windows dans une fenêtre bash de cygwin. Là, tu disposeras de toute la puissance et mémoire de la machine réelle.

Discussions similaires

  1. [MySQL] temps d'execution d'un script sur un serveur web
    Par cerco1 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 29/10/2011, 19h30
  2. Diminuer le temps d'execution d'une application
    Par javatar dans le forum Général Java
    Réponses: 6
    Dernier message: 27/11/2010, 14h44
  3. [AC-97] Optimiser une requête pour diminuer le temps d'execution
    Par Milyshyn76 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 31/05/2010, 13h22
  4. temps d'execution d'un script
    Par kevin07 dans le forum Linux
    Réponses: 6
    Dernier message: 29/07/2009, 16h38
  5. Temps d'execution d'un script c++ sous linux
    Par sharantyr dans le forum Linux
    Réponses: 10
    Dernier message: 04/06/2006, 19h51

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