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 :

Optimisation d'un script Bash


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 6
    Par défaut Optimisation d'un script Bash
    Bonjour !

    J'ai un script bash à optimiser, il s’exécute en 200 ms, il faudrait qu'il descende en dessous des 50 ms . Quand je parle de l'exécution, je veux parler d'un parcours total de la boucle While)

    J'ai beaucoup de mal à l'optimiser, connaissant mal ce langage.. Je sais par exemple qu'il faut limiter les appels extérieurs, mais difficile à mettre en pratique ^^

    Voici le 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
    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
    #!/bin/bash
    #
    ##### take_screenshot #####
    #
    # Permet de capture l'image d'un display
    #
    # Param 1 = Display
    # Param 2 = Token
    #
    *
    display=$1
    token=$2
    *
    counter=0
    is_closed=0
    errorCounter=0
    *
    import -display :$display -window "$token" ../tmp/$token.png > /dev/null
    cp ../tmp/$token.png ../tmp/import_$token.png
    cp ../tmp/$token.png ../tmp/import_$token"_tmp_1.png"
    *
    while [ $is_closed -eq 0 ]; do
    *
    #################################
    #
    # CAPTURE_FENETRE_PRINCIPALE
    #
    #################################
    *
    **#TEST DE FERMETURE DE LA FENETRE
    **retour=$(DISPLAY=:$display xdotool search --name "$token")
    *
    **if [ $retour -z ]
    **then
    ****if [ $errorCounter -ge 20 ]
    ****then
    *******is_closed=1
    *******./log.sh "log_flux.txt" "Fermeture brutale de $token survenue" &
    ****fi*
    ****errorCounter=$(($errorCounter+1))
    **else
    ****errorCounter=0
    **fi
    **#FIN DE TEST
    *
    **info=$(xwininfo -name "$token" -display :$display)
    **width_actu=$(echo $info | awk {'print $25'})
    **height_actu=$(echo $info | awk {'print $27'})
    *
    **offsetX=$(echo $info | awk {'print $11'})
    **offsetY=$(echo $info | awk {'print $15'})
    *
    **import -display :$display -screen -window root -crop $width_actu"x"$height_actu"+"$offsetX"+"$offsetY ../tmp/$token.png
    *
    **cp ../tmp/$token.png ../tmp/import_$token.png &
    **cp ../tmp/$token.png ../tmp/import_$token"_tmp_2.png" &
    *
    #################################
    #
    # CAPTURE_MULTI_FENETRAGE
    #
    #################################
    *
    ***window_list=$(./get_all_window.sh $token)
    *
    ***for word in $window_list
    ***do
    ******if [ "$word" != "$token" ]
    ******then
    *****#Si l'image root n'existe pas, on la créer
    *****if [ test -f ../tmp/import_$word"_tmp_1.png" ]
    *****then
    ********import -display :$display -window "$word" ../tmp/$word.png > /dev/null
    ********cp ../tmp/$word.png ../tmp/import_$word.png
    ********cp ../tmp/$word.png ../tmp/import_$word"_tmp_1.png"
    *****fi
    *
    *****info=$(xwininfo -name "$word" -display :$display)
    *****width_actu_child=$(echo $info | awk {'print $25'})
    *****height_actu_child=$(echo $info | awk {'print $27'})
    *
    *****offsetX_child=$(echo $info | awk {'print $11'})
    *****offsetY_child=$(echo $info | awk {'print $15'})
    *
    *****import -display :$display -window root -crop $width_actu_child"x"$height_actu_child"+"$offsetX_child"+"$offsetY_child ../tmp/$word.png > /dev/null
    *********cp ../tmp/$word.png ../tmp/import_$word.png &
    *****cp ../tmp/$word.png ../tmp/import_$word"_tmp_2.png" &
    ******fi
    ***done
    done
    Quelques conseils d'optimisations serait les bienvenues !

    En vous remerciant d'avance,

    Bonne journée

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 134
    Par défaut
    Dans le style d'appel externe que l'on peut éviter, c'est l'utilisation de awk là où un simple cut répondrait au besoin...
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 6
    Par défaut
    Bonjour,

    Tout d'abord merci pour votre réponse !

    En effet, je vais remplacer les awk par des cut. Mise à part ce cas, comment savoir, de façon générale, quelle commande externe est la plus légère ? Ou peut être que cut est présent directement dans le build bash, contrairement à awk ?

    --

    Dans ce script, 75% du temps de traitement correspond à l'import d'imageMagick, qui représente 150ms. Je ne suis pas sur que cette ligne peut être améliorée..

    Je vais déjà commencer par remplacer les awk par des cut ! .

    Merci encore.

  4. #4
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    déjà vouloir optimiser -en rapidité- du bash ça me semble relativement hérétique, bash est ce qui se fait de plus lent, particulièrement sur les boucles

    effectivement t'as 4x le même genre de ligne dans ton code du genre var=$(echo $machin | awk), ce qui fait spawn 4x awk pour rien, je te propose -et ça peut sûrement encore être amélioré- :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    read width_actu_child height_actu_child offsetX_child offsetY_child <<< "$(awk 'printf ("%s %s %s %s", $25, $27, $11, $15)' <<< "$info")"
    et si tu voulais complètement te passer des temps de création de processus, ben tu coderais le tout en Perl, en Python, voire carrément en C

    mais l'essentiel de ton traitement ne vient pas de bash, grosso modo ton code peut être perçu comme suit :
    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
    while
       xdotool
       ./log.sh
       xwininfo
       awk (x4)
       import
       cp (x2)
       ./get_all_window.sh
       for
          import
          cp (x2)
          xwininfo
          awk (x4)
          import
          cp (x2)
       done
    done
    à vue de nez je dirais :
    • qu'il faut se pencher également sur les deux autres scripts bash appelés (quel est leur impact ?)
    • qu'il y a beaucoup d'opérations disque, que tu auras du mal à optimiser, à moins de passer sur un ssd peut-être ? ^^
    • que le coupable idéal ce serait bien import, sur lequel tu n'as pas de contrôle non plus donc l'optimisation s'arrête ici possiblement
    • qu'in fine le mieux pour en avoir le coeur net serait encore de bencher/chronométrer chaque opération (en feintant comme expliqué ici par exemple)

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 6
    Par défaut
    Bonjour,

    Merci pour ton analyse .

    En effet déclarer qu'un seul awk me semble beaucoup mieux !

    --

    Je pensais également à me tourner vers le Python, ou peut être le dash, mais comme tu le disais, l'essentiel du temps de traitement vient de scripts externe, donc le bash peut surement convenir.

    J'avais déjà timé chaque instruction, et le import occupe 150 ms sur les 200 ms que prend une boucle complète.

    --

    Les scripts externes log.sh et get_all_windows.sh possède un temps de traitement négligeable ^^.

    Je pense que tu as raison, je pourrais peut être gagner quelque milliseconde, mais difficile de diviser le temps par deux, même en optimisant et en adoptant python ou perl, étant donné que le traitement vient de fichiers externes..

    Merci en tout cas .

  6. #6
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 348
    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 348
    Par défaut
    Bonjour,

    Tu dois pouvoir gagner un peu de temps, si tu te passes de tout tes cp qui semble redondant et si tu fait tes imports en background et directement dans le fichier final qui semble être à chaque fois le dernier cp.
    En exemple, les lignes 18,19 et 20 deviendraient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import -display :$display -window "$token" ../tmp/import_$token"_tmp_1.png" > /dev/null &
    #cp ../tmp/$token.png ../tmp/import_$token.png
    #cp ../tmp/$token.png ../tmp/import_$token"_tmp_1.png"
    et avant de sortir de ton script, il faut juste rajouter la commande wait

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

Discussions similaires

  1. Requête POST dans un script bash
    Par desperado dans le forum Linux
    Réponses: 4
    Dernier message: 11/12/2007, 22h38
  2. Réponses: 21
    Dernier message: 29/09/2005, 19h33
  3. Script bash : Pb avec sed
    Par fred64 dans le forum Linux
    Réponses: 3
    Dernier message: 19/08/2005, 11h24
  4. Scripts bash : requêtes sql
    Par milka dans le forum Linux
    Réponses: 3
    Dernier message: 17/08/2005, 10h59
  5. Problème script Bash
    Par Sphost dans le forum Linux
    Réponses: 10
    Dernier message: 26/07/2005, 09h56

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