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

Shell et commandes GNU Discussion :

Piste d'amélioration de la vitesse d'un script


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Piste d'amélioration de la vitesse d'un script
    Bonjour,

    C'est un peu la suite du poste ici

    Je récupère un numéro à partir du nom du fichier (du caractère 4 au 21) qui peut avoir des zéros au début (et c'est quasi toujours le cas)
    J'utilise donc la commande suivante pour le récupérer (le echo est là car je récupère le nom du fichier via une requête SQL, plus exactement une liste de fichier)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    numero=`echo "$fichier" | cut -c 4-21 | sed 's/^0*//'`
    echo $numero
    41
    Je récupère toute les lignes de 11 caractères : cela peut être de la forme "ABCD 000001" ou "ABCDE0999999"
    Je remplace l'espace par le symbole "_" pour pouvoir utiliser le résultat dans une liste.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    liste_ligne_nb_cr_type=`awk 'length == 11 { sub(/ /,"_",$0); print $0 }' output/$fichier`
    echo $liste_ligne_nb_cr_type
    AB13_000023 AB123000023
    Voici la partie à optimiser:
    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
     
          for fichier in $liste_fichier
          do
     
            #On récupére le numéro de l'abonné : ABC000000000000000041xxxxxxxxxxxxxxxxxxxxxxxxxxxx => 41
            numero_abonne=`echo "$fichier" | cut -c 4-21 | sed 's/^0*//'`
     
            #Ne garder que les en-tête évènement = Ligne de 11 caractères commençant par une lettre (on y remplace l'espace par "_" pour l'avoir en un seul morceau)
            liste_ligne_nb_cr_type=`awk 'length == 11 { sub(/ /,"_",$0); print $0 }' output/$fichier`
     
            for ligne_nb_cr_type in $liste_ligne_nb_cr_type
            do
              #Nombre de CR associé à ce type de cr (AB13_000023 => 23)
              nb_cr=`echo $ligne_nb_cr_type | sed 's/.....0*\(.*\)/\1/'`
              #Abonné associé à son type de CR sous la forme : AB13__41 / AB123_41 ( "type cr" _ "numéro abonné" )
              type_subscriber=`echo $ligne_nb_cr_type | sed "s/\(.....\).*/\1_$numero_abonne/"`
              #On l'ajoute à la liste des abonnés associés à leur type de CR
              liste_type_subscriber+=" $type_subscriber"
              #Cumuler le nombre de CR pour chaque type
              eval $type_subscriber=$(($type_subscriber + $nb_cr))
            done
          done
          #On trie les abonnés associés à leur type de CR (en enlevant les doublons)
          liste_type_subscriber_unique=`for type_subscriber in $liste_type_subscriber; do echo $type_subscriber; done | sort -u`
    J'avais pensé à tester si l'abonné existait déjà dans la liste "liste_type_subscriber" avant de l'ajouter. Mais il semble plus efficace de tous les ajouter puis de faire un sort à la fin.
    Je pourrais essayer de me servir du awk pour faire les calculs, mais il ne semble pas possible d'utiliser une variable externe afin de la modifier ...
    Je stocke tout en mémoire plutôt que dans des fichiers car cela devrait être plus rapide.

    Auriez-vous des idées d'optimisation ?

    Merci

    ps: le code était moins rapide avant
    Dernière modification par Invité ; 11/03/2014 à 23h08.

  2. #2
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 291
    Par défaut
    Bonjour

    Entendre "bash" et "optimisation" dans la même phrase me fait sourire. Bash est un script pour faire facilement des tâches idiotes. Il est très lent.

    Si tu veux de l'optimisation, fais du C++ ou java. Surtout pour travailler des caractères; ce n'est pas hors de portée.

  3. #3
    Modérateur
    Avatar de ggnore
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    2 472
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 2 472
    Par défaut
    Tu pourrais aussi faire du perl : tu n'aurais pas à lancer des sed à gogo. C'est très adapté pour parser du texte et vraiment pas très éloigné du shell.
    Si tu veux évaluer le temps d'exécution de ton script utilise la commande time. Il te faut mesurer le temps d'exécution, plutôt que d'utiliser le conditionnel
    ça devrait aller plus vite
    Toutes les vertus des hommes se perdent dans l’intérêt comme les fleuves se perdent dans la mer.
    N'oubliez pas de consulter les FAQ Linux et les cours et tutoriels Linux

  4. #4
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 349
    Par défaut
    Bonjour,

    En étant plus clément et en regardant rapidement, la dernière boucle for me parait inutile, et je pense même que l'on doit pouvoir faire la même chose sans toutes ces boucles.
    Tu dois pouvoir récupérer l'ensemble des informations que tu as besoin avec une seule commande sed...
    Mais bon, c'est un regard très rapide...

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par ggnore Voir le message
    Tu pourrais aussi faire du perl : tu n'aurais pas à lancer des sed à gogo. C'est très adapté pour parser du texte et vraiment pas très éloigné du shell.
    Si tu veux évaluer le temps d'exécution de ton script utilise la commande time. Il te faut mesurer le temps d'exécution, plutôt que d'utiliser le conditionnel
    Oui la commande time est bien pour tester tout cela. C'est ce que j'ai fait
    Mais comme je n'ai pas fait de tests sur l'architecture finale, je ne peux pas être sûr à 100%. La quantité de fichiers à traiter et la vitesse des disque sera différent.

    Citation Envoyé par Flodelarab Voir le message
    Bonjour

    Entendre "bash" et "optimisation" dans la même phrase me fait sourire. Bash est un script pour faire facilement des tâches idiotes. Il est très lent.

    Si tu veux de l'optimisation, fais du C++ ou java. Surtout pour travailler des caractères; ce n'est pas hors de portée.
    Je suis d'accord. Mais dans ce cas, il faut demander l'aide d'une personne connaissant java et c'est ça le problème... A mois que j’apprenne le java sur mon temps libre pour le boulot
    Enfin, si on a toujours des problèmes pour avoir la liste des fichiers à analyser, on passera peut-être au java (une autre méthode pour récupérer cette liste l'utilise)
    Bon en tout cas l'optimisation du script fonctionne bien. On passe de 20-30min à 3-6min

    Citation Envoyé par disedorgue Voir le message
    Bonjour,

    En étant plus clément et en regardant rapidement, la dernière boucle for me parait inutile, et je pense même que l'on doit pouvoir faire la même chose sans toutes ces boucles.
    Tu dois pouvoir récupérer l'ensemble des informations que tu as besoin avec une seule commande sed...
    Mais bon, c'est un regard très rapide...
    Je ne vois pas d'autre manière de supprimer les doublons d'une liste. Je suis preneur car je n'aime pas cette méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ echo $liste
    abc def ghi abc def ghi
     
    $ echo $liste | sort -u
    abc def ghi abc def ghi
    Enfin, si un coup de sed pour changer les espace par des retours chariot, mais dans ce cas ce serait plus long que la boucle for (testé avec la commande time)

    Je pense aussi comme toi qu'on doit pouvoir se passer de la boucle pour l'autre partie. Le poste suivant me donne une idée : lien
    Je vais voir ce que ça donne au final.

  6. #6
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 349
    Par défaut
    Exemple de remplacement de ta dernière boucle (il faut respecter le retour à la ligne):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ echo $liste
    abc def ghi abc def ghi abc def ghi abc def ghi
    $ sort -u - <<<"${liste// /
    }"
    abc
    def
    ghi
    Pour le reste du code, il faudrait un input et un output d'exemple sur lequel on peut travailler si tu veux que l'on t'aide à améliorer les perfs.

    PS: perso, je ne pense pas que java serait le meilleur choix si le shell ne suffisait pas, perl ou python suffirait largement

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

Discussions similaires

  1. Amélioration de la vitesse de 1er chargement
    Par Sankasssss dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 22/09/2009, 17h46
  2. Réponses: 6
    Dernier message: 30/06/2008, 10h14
  3. Améliorer la vitesse de parcours d'un gros recordset
    Par Vld44 dans le forum Vos contributions VB6
    Réponses: 8
    Dernier message: 28/01/2008, 01h15
  4. Evaluer la vitesse d'un script ?
    Par reski dans le forum Langage
    Réponses: 3
    Dernier message: 19/06/2007, 00h31

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