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 :

Cherche une solution pour optimiser un script


Sujet :

Langage Perl

  1. #1
    Membre du Club
    Inscrit en
    Décembre 2008
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 57
    Points : 41
    Points
    41
    Par défaut Cherche une solution pour optimiser un script
    Bonjour à tous,

    Débutant sous perl, j'essaye d'optimiser un script car celui-ci prend trop de temps à mon goût ^^
    Soit car il n'est pas possible de faire autrement soit car il y a un problème de conception...

    Le script actuel lit un fichier de 1 millions de lignes voir 3, ligne à ligne, et exécute une série de tests sur des données (une BDD extraite dans un hash à plusieurs dimensions mit dans un module généré à partir d'un awk, car je me suis dit que cela serait plus rapide que de faire 36 millions de requêtes vers Mysql)

    Ex du hash: (le vrai contient plus de 200 ID1, qui contiennent chacun en général une 20aine d'ID2, qui eux même contiennent bien souvent plus de 300 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
     
    our %bdd =      (
     
                    150230 =>    #ID1
                            {
                                    360789 => #ID2
                                            {
                                                    123456 => #CODE
                                                            {
                                                                     infos1 => 'du texte',
                                                                     infos2 => ['a','b','c']
                                                            },
                                            }
                             }
                          );
    Pour accéder aux clefs du hash que je souhaite utilisé selon la ligne dans ma boucle while (<>) je fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
           for my $code ( keys %{$bdd{$ID1_FICHIER}{$ID2_FICHIER}} )
            {
            }
    $ID1_FICHIER et $ID2_FICHIER correspondant aux ID récupéré dans les champs de mon fichier

    Le parcours se fait sans encombre et c'est super rapide. Si je fais aucun test dans ma boucle sur le contenu des clefs du code parcouru en cours ,le temps d'exécution est super rapide (2min pour 1.5 millions de lignes).

    Par contre dès lors que je fais un test du genre, le temps d'exécution augmente énormément:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
           if($bdd{$ID1_FICHIER}{$ID_FICHIER2}{$code}{info1} eq 'du blabla')
           {
           }
    J'ai aussi tenté de créer une référence sur ce code juste au début de mon 'for' et de l'utiliser dans ma condition, mais le temps de créer la référence + faire le test augmente encore un peu le temps d'execution ^^

    Je voulais donc tester de créer un hash pour chaque code contenant les infos genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    %hash_code_25689 = (
                                   info1 => 'du texte'
                                  )
    Mais je n'arrive pas à trouver l'astuce qui ferais que si j'avais $code=25869, je pourrais accéder à mon hash genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    print $hash_code_${256869};
    Y'a t'il un moyen de procéder comme ceci? et cela améliora t'il à votre avis le temps d'accès aux infos pour faire mes test?

    Ou avez-vous d'autres idées qui pourrait m'aider à améliorer les performances de tout ca? , car je comprends bien que d'ajouter un test dans ma boucle augmente le temps mais delà à passer de 2min à plus de 15min juste pour faire un if $tata eq 'bob' me parait un peu bizzard , non?

    Merci pour vos compléments d'information

    Cdt,

  2. #2
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Vu que personne ne semble avoir d'idées, je vais proposer les miennes mais ce sont peut-être de mauvaises idées :

    au lieu de créer un hash par code ... ce qui va en faire énormément
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    my %hash_code_25689 = (
                                   info1 => 'du texte'
                                  )
     
     
    print $hash_code_${256869};
    Tu pourrais utiliser un array, si il n'y a pas deux fois le même code !!!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    my @array_code;
    $array_code[25689]->{info1} = 'du blabla';
     
     
    if( $array_code[$code]->{info1} eq 'du blabla'){
    	print "blabla\n";
    }

    ou au lieu de %bdd contenant 3 clés : concaténer tes clés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    my %hash_code;
    my ($ID1_FICHIER, $ID2_FICHIER, $code) = (150230, 360789, 123456);
    $hash_code {$ID1_FICHIER.'_'.$ID2_FICHIER.'_'.$code}->{infos1} = 'du blabla';
    $hash_code {$ID1_FICHIER.'_'.$ID2_FICHIER.'_'.$code}->{infos2} = ['a','b','c'];
     
    for my $k ( keys %hash_code){
    	my ($ID1_FICHIER, $ID2_FICHIER, $code) = split /_/, $k;
            print "$code\n";
    }
    mais bon, ça dépend de ce que tu veux faire avec ton tableau
    ... au niveau performances, je ne sais pas si c'est mieux, il faut tester.
    -- Jasmine --

  3. #3
    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
    Ensuite si tu es sur un machine multiprocesseur tu peux essayer de te multithreader pour utiliser les autres processeurs.

    si tu es en mono proc oublie cette remarque.
    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

  4. #4
    Membre du Club
    Inscrit en
    Décembre 2008
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 57
    Points : 41
    Points
    41
    Par défaut
    Je vais étudier ca de plus près ^^

    Je me suis bien acharné dessus ce week end et j'ai bien améliorer les choses même si j'ai globalement pas tout fini ca avance bien

    Pour ce qui est de la concaténation des variables, ça pose pas de soucis avec le pragma "use strict" ? car j'ai souvenir d'avoir développé mon premier test ainsi et qu'avec ce pragma perl n'était pas très très content (souvenir obscure..)

    Sinon pour accélérer tout se petit monde , j'ai créer 3 hash, un contenant les id1 l'autre les id2 et un autre avec les infos des codes , tout en utilisant des références à chaque fois

    Après pour encore aller un peu plus loin j'ai commencé à réécrire mes fonctions pour que je puisse m'en servir avec Memoize ( l'accélération des tests a été surprenante!! ) et à revoir certaines méthodes d'accès à mes données

    Sinon pour le multithread (serveur 8 CPU), je me pencherai la dessus une fois le script fini et mes compétences revues ^^ . Pour le moment je fais du Multi via un script Shell bien pratique mais génant car le script inclue autant de fois mon module etc.. que de process

    Je vous tiens au jus pour cloturer le topic une fois la chose bouclée au cas où d'autres soucis se pose à moi

    Merci

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

Discussions similaires

  1. Cherche une solution pour addition (sans PHP)
    Par Gui de nlc dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/04/2013, 14h30
  2. je cherche une solution pour cet exercice
    Par rafikadouni dans le forum Débuter
    Réponses: 4
    Dernier message: 22/11/2007, 22h26
  3. Réponses: 1
    Dernier message: 11/10/2007, 13h24
  4. Y a-t-il une solution pour optimiser mon petit code ?
    Par pierre987321 dans le forum Delphi
    Réponses: 20
    Dernier message: 14/06/2007, 10h53

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