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 :

demande de conseil pour optimiser mon script


Sujet :

Shell et commandes GNU

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2009
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 12
    Points : 11
    Points
    11
    Par défaut demande de conseil pour optimiser mon script
    bonjour,

    voilà, je suis débutant en bash. ceci est en fait mon 1er script. ça m'a pris quelques jours pour en arriver là (et quelques posts sur le forum).
    le résultat fait exactement ce que je veux mais est incroyablement lent. mon pc n'est pas une bête de compét, mais à la vitesse où ça avance, il y en a pour plusieurs jours de calcul....
    je me dis que je n'ai pas forcément choisi les solutions les plus rapides de calcul. mais pour l'instant, je n'en connais pas d'autres...
    alors, ce serait sympa si quelqu'un pouvait me donner quelques pistes pour optimiser mon script
    ce script fait des profils swath (sur une bande de 10km de large, on calcule l'altitude moyenne, les valeurs min et max; et ceci pour chaque point du profil (environ une valeur tous les 90mètres, sur un profil d'environ 350km de long)


    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
    # definition du nom de sortie à partir des coordonnées de la coupe
    separe1_name=$(echo $start_proj | awk -F "/" '{print $1}')
    separe2_name=$(echo $start_proj | awk -F "/" '{print $2}')
    separe3_name=$(echo $end_proj | awk -F "/" '{print $1}')
    separe4_name=$(echo $end_proj | awk -F "/" '{print $2}')
    name_output=$separe1_name"-"$separe2_name"-"$separe3_name"-"$separe4_name
     
    >mean_$name_output.txt
    >min_$name_output.txt
    >max_$name_output.txt
     
    mean_y=0
    min_y=10000
    max_y=0
    compteur=0
     
    while read pos val
    do
     
    x=$(printf "%.2f\n" $pos)       #on arrondit pos à 2 chiffres après la virgule
     
    y=$(printf "%.2f\n" $val)       #on arrondit val à 2 chiffres après la virgule 
     
    if [ $(echo "$y < 0.00" | bc) -eq 1 ]; then    #on élimine z négatif et NaN
    y=0                                    #si le test est vrai (y<0),il renvoie 1 
    fi                                             #on remplace y par 0

    # du à l'effet combiné de l'arrondi des valeurs (par printf) issues de gmt_project, des valeurs correspondant à la même ligne de SRTM sont quelquefois espacées de 0.01. on fait donc un test: si seulement l'écart est supérieur à 0.01, on considère qu'on est passé à une nouvelle ligne de données)

    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
    diff=$(echo "$x-$i" | bc)
     
        if [ $(echo "$diff <= 0.01" | bc) -eq 1 ]
            then mean_y=$(echo "$mean_y+$y" | bc)
            ((compteur = $compteur + 1))
            if [ $(echo "$y < $min_y" | bc) -eq 1 ]; then
            min_y=$y
            fi
            if [ $(echo "$y > $max_y" | bc) -eq 1 ]; then
            max_y=$y
            fi
        else
            mean_y=$(echo "$mean_y/$compteur" | bc)
            echo $i $mean_y >> mean_$name_output.txt
    echo position:$i moyenne:$mean_y min:$min_y max:$max_y compteur:$compteur
            echo $i $min_y >> min_$name_output.txt
            echo $i $max_y >> max_$name_output.txt
     
                    i=$x                        # on change la valeur de i
            mean_y=$y
            max_y=$y
            min_y=$y
            compteur=1
        fi
     
    done < $fich

    merci d'avance,
    seb

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 578
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 578
    Points : 19 439
    Points
    19 439
    Par défaut
    Bonjour,

    tu devrais tout passer sous awk.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Tu n'es pas obligé d'utiliser bc pour toutes tes opérations : bash permet de faire des comparaisons et des calculs simples

    Sinon, le script me paraît affreusement compliqué pour un problème à première vue assez simple : j'ai cru comprendre que tu avais un fichier en entrée qui comporte 2 valeurs par ligne (x et y) mais le coup des arrondis et la gestion des positions m'échappent un peu par rapport à ton traitement, donc si tu pouvais donner le format et un exemple de ton fichier en entrée, ça pourrait aider à te proposer mieux.

    Sinon, effectivement, utiliser awk ou perl pour tout faire semble une bonne approche (mais pas forcément indispensable à mon avis).

  4. #4
    Membre à l'essai
    Inscrit en
    Janvier 2009
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    bonjour,

    réponse avec un peu de retard (en fait, je viens juste de finir de le réécrire en awk comme suggéré par N BaH). ca tourne impec et rapidement. merci

    Il s'agit de mon 1er script awk. peut sûrement mieux faire....

    Alek-C:
    Comme tu peux voir, je ne passe plus par le calcul des arrondis (ca prend énormément de temps de calcul)

    Je lance ce script depuis un script bash (j'en ai besoin pour faire tourner des trucs qui ne marchent pas sous awk)

    partie du script bash:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    n=$(wc -l strip_sampling_$name_output.pz | gawk '{print $1}')
    gawk -f E:/GMTscripts-grd/PARAM/swath.gawk n=$n < strip_sampling_$name_output.pz
    script awk:
    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
    #!/bin/gawk -f
     
     
    BEGIN {
    i = 0
    sum_y = 0
    min_y = 10000
    max_y = 0
    compteur = 0
    }
     
    {
    for (k=1 ; k<=n ; k++)
    {
    getline 
     
    #toutes les altitudes inférieures à 0 sont corrigées
    	if ($2 < 0)
    	{
    	$2=0
    	}
     
    diff=$1-i
    	if (diff <= 0.02)
    		{
    		sum_y=sum_y+$2
    		compteur=compteur+1
    		if ($2 < min_y) min_y = $2 
    		if ($2 > max_y) max_y = $2
    		}
    	else
    		{
    		mean_y=sum_y/compteur
    print "position:"i, "sum:"sum_y, "moyenne:"mean_y, "min:"min_y, "max:"max_y, "compteur:"compteur
    		print i, mean_y >> "mean.txt"
                    print i, min_y >> "min.txt"
    		print i, max_y >> "max.txt"
    		i=$1
    		sum_y=$2
    		max_y=$2
    		min_y=$2
    		compteur=1
    		}	
     
    }
    }
    Mon fichier d'entrée résulte de la projection (par l'outil project de GMT www.soest.hawaii.edu/gmt/) de tous les points (longitude, latitude, altitude) situés à 5km de part et d'autre d'un trait de coupe. J'ai donc un fichier (p,z), p étant le projeté de (longitude,latitude) sur mon trait de coupe, exprimé en distance kilométrique depuis le début du trait de coupe. Mon trait de coupe pouvant être oblique, je ne peux pas me contenter de la latitude ou de la longitude des points. Tout le problème vient que le résultat de project donne des valeurs de p différentes pour, par exemple, des points situés à la même latitude le long d'un profil Nord-Sud (voir exemple ci-dessous). Les écarts sont très faibles mais m'empêche de calculer directement la moyenne et de déterminer les valeurs min et max pour toutes les données perpendiculaires en chaque point au profil (à la même latitude dans le cas d'un profil N-S). L'astuce que j'ai trouvé, sachant que j'ai un point tous les 90mètres dans ma base de données topographiques (SRTM de la NASA) est de comparer la distance entre 2 points successifs (nommé diff dans le script awk). Si elle est inférieure à un certain seuil (ici 0.02), alors ces points sont sur la même latitude.

    Voici un exemple de fichier d'entrée (p,z). p est en kilomètre, z est en mètre.

    0.00184575568891 0.00028742471477
    0.00184575568891 376.046569824
    0.00189395585363 395.98916626
    0.00189395585363 4.1547946239e-007
    0.00194791213731 414.259521484
    0.00194791213731 0.000286347582005
    0.0926625226018 0.00034032255644
    0.0926628630255 0.000665176485199
    0.0926628630255 0.000674647395499
    0.092663884289 0.000669857836328
    0.092663884289 0.000651132315397
    0.0926655377394 0.000326278415741


    seb
    ps: pour ceux qui se demandent à quoi tout ca sert, je suis géologue. c'est pour faire des profils topo dans les alpes

  5. #5
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Beau travail

    Ajoute juste des balises CODE autour de ton programme et ça sera parfait

    Et clique sur résolu pendant que tu y es :p

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

Discussions similaires

  1. Demande de conseils pour optimisation
    Par gitney dans le forum jQuery
    Réponses: 4
    Dernier message: 06/04/2013, 13h02
  2. Réponses: 2
    Dernier message: 24/10/2012, 10h25
  3. [XL-2010] Demande d'aide svp pour corriger mon script
    Par developpeur82 dans le forum Macros et VBA Excel
    Réponses: 14
    Dernier message: 06/09/2012, 12h03
  4. PreparedStatment : conseils pour optimiser mon code
    Par Monkey_D.Luffy dans le forum JDBC
    Réponses: 8
    Dernier message: 30/05/2008, 13h49

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