OVH Cloud OVH Cloud

optimisation...

8 réponses
Avatar
kurtz_le_pirate
bonjour,

j'ai un fichier qui contient des sdonnées sous cette forme :
Time,Total Host Req/s,Total Host MB/s,Node
29/Nov/2006 17:19:19,113,0.59,EVA3000

Time,Total Host Req/s,Total Host MB/s,Node
29/Nov/2006 17:19:24,163,0.85,3000

...
...

le but est de récupérer les deux valeurs après la date dans la
deuxième ligne.
j'ai fait ce script qui marche bien :
while (<SOURCEFILE>) {
next if /^time/i;
next if /^\n/;
chomp;
s/,/-/g;
s/\./,/g;
($date,$val1,$val2,$val3) = split /-/;
print RESULTFILE "$count\t$val1\t$val2\n";
$count++;
}

mais, je me demande s'il vaut mieux :
- reconnaître la deuxième ligne et traiter celle çi
ou (comme je l'ai fais)
- ignorer la première ligne et la ligne vide et traiter celle qui
reste ?

ceci pour des questions de perfs car je peux avoir des fichier assez
gros (>5Mo)


merci pour votre avis


--
klp

8 réponses

Avatar
Paul Gaborit
À (at) Fri, 1 Dec 2006 15:14:01 +0100,
"kurtz_le_pirate" écrivait (wrote):
j'ai un fichier qui contient des sdonnées sous cette forme :
Time,Total Host Req/s,Total Host MB/s,Node
29/Nov/2006 17:19:19,113,0.59,EVA3000

Time,Total Host Req/s,Total Host MB/s,Node
29/Nov/2006 17:19:24,163,0.85,3000

...
...

le but est de récupérer les deux valeurs après la date dans la
deuxième ligne.
j'ai fait ce script qui marche bien :
while (<SOURCEFILE>) {
next if /^time/i;
next if /^n/;
chomp;
s/,/-/g;
s/./,/g;
($date,$val1,$val2,$val3) = split /-/;
print RESULTFILE "$countt$val1t$val2n";
$count++;
}

mais, je me demande s'il vaut mieux :
- reconnaître la deuxième ligne et traiter celle çi
ou (comme je l'ai fais)
- ignorer la première ligne et la ligne vide et traiter celle qui
reste ?

ceci pour des questions de perfs car je peux avoir des fichier assez
gros (>5Mo)


Le plus simple serait peut-être de se baser sur le numéro de ligne (si
le fichier est réellement régulier). Un truc du genre :

next if $.%3 != 2;

L'appel à 'chomp' ne sert a rien.

Les deux substitutions sont aussi très gourmandes. Une simple
translittération serait plus efficace :

tr/,./-,/;

Les variables $date et $val3 ne servent à rien. On peut donc écrire :

(undef,$val1,$val2,undef) = split /-/;

ou :

($val1,$val2) = (split /-/)[1,2];

PS: si 'assez gros' commence à 5Mo pour vous, que direz-vous lorsque
vosu traiterez des fichiers de 100Go ?

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
kurtz le pirate
In article ,
Paul Gaborit wrote:


Le plus simple serait peut-être de se baser sur le numéro de ligne (si
le fichier est réellement régulier). Un truc du genre :

next if $.%3 != 2;


oui, le fichier "régulier".
mais je ne connais pas cette fonctionnalité :(


L'appel à 'chomp' ne sert a rien.


ha ?

Les deux substitutions sont aussi très gourmandes. Une simple
translittération serait plus efficace :

tr/,./-,/;


j'y avais pensé, mais je me demandais si l'ordre des translittérations
serait respecté et que le séparateur de valeur ne se mélange pas avec le
séparateur décimal. je vais tester ça.


Les variables $date et $val3 ne servent à rien. On peut donc écrire :

(undef,$val1,$val2,undef) = split /-/;


ça aussi de ne connaissait pas :(( (le split oui bien sur, le undef dans
une liste non).


ou :

($val1,$val2) = (split /-/)[1,2];
et ça encore moins quoique très logique :(((



PS: si 'assez gros' commence à 5Mo pour vous, que direz-vous lorsque
vosu traiterez des fichiers de 100Go ?


en fait je pense que le plus gros fichier pourrait faire 50Mo (80 car x
86400 mesures/jour x 7 jours)... très loin des 100Go !

je suis petit jouer, lol


merci surtout pour m'avoir fait découvrir ces nouveautés !


--
klp

Avatar
kurtz le pirate
j'ai modifié mon script avec ces nouvelles idées et fais des tests sur
un fichier un peu plus gros : 280Mo.

while (<SOURCEFILE>) {
next if ($.%3) != 2;
tr/,./#,/;
($date,$val1,$val2,undef) = split /#/;
print RESULTFILE "$datet$val1t$val2n";
$count++;
}
s'execute en 53". l'utilsation de la mémoire reste constante.




while (<SOURCEFILE>) {
next if /^time/i;
next if /^n/;
chomp;
s/,/-/g;
s/./,/g;
($date,$val1,$val2,$val3) = split /-/;
print RESULTFILE "$countt$val1t$val2n";
$count++;
}

se plante à environ 50% du traitement avec un "not enough memory"!

je pensais que les deux substitutions étaient gourmandes en 'temps' pas
en mémoire qu'apparemment, elles ne libèrent pas !



--
klp
Avatar
Paul Gaborit
À (at) Fri, 01 Dec 2006 19:37:43 +0100,
kurtz le pirate écrivait (wrote):
L'appel à 'chomp' ne sert a rien.


ha ?


Cette remarque n'est évidemment valable que dans votre contexte
précis.

La fonction 'chomp' est très utile pour enlever les éventuels
caractères de passage à la ligne en fin de chaîne. Mais dans votre
cas, vous n'utilisez pas la fin de la chaîne, c'est donc inutile.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>


Avatar
Paul Gaborit
À (at) Sat, 02 Dec 2006 17:54:55 +0100,
kurtz le pirate écrivait (wrote):
j'ai modifié mon script avec ces nouvelles idées et fais des tests sur
un fichier un peu plus gros : 280Mo.
[... premier script...]

s'execute en 53". l'utilsation de la mémoire reste constante.
[...deuxième script...]

se plante à environ 50% du traitement avec un "not enough memory"!


Ça m'étonne beaucoup. Le script tel quel n'a aucune raison de
conserver des choses en mémoire.

je pensais que les deux substitutions étaient gourmandes en 'temps' pas
en mémoire qu'apparemment, elles ne libèrent pas !


Est-ce vraiment la seule chose qu'il y a dans le script ?
Sur quelle version de Perl ?

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
espie
In article ,
Paul Gaborit <Paul.Gaborit+ wrote:

À (at) Fri, 01 Dec 2006 19:37:43 +0100,
kurtz le pirate écrivait (wrote):
L'appel à 'chomp' ne sert a rien.


ha ?


Cette remarque n'est évidemment valable que dans votre contexte
précis.

La fonction 'chomp' est très utile pour enlever les éventuels
caractères de passage à la ligne en fin de chaîne. Mais dans votre
cas, vous n'utilisez pas la fin de la chaîne, c'est donc inutile.


Hum, je suis d'accord avec toi techniquement, mais pas sur le plan
du style.

Lors de la lecture d'un fichier quelconque, je fais des chomp de
facon systematique, que je joue avec la fin de ligne ou pas...

Dans 99% des cas, ca marche comme je veux, ca me permet de normaliser
les choses, d'avoir des lignes sans "n" a la fin, voire meme mieux,
lorsqu'il s'agit de filtrer un fichier, ca me sert a le renormaliser,
en m'assurant que j'aurais bien exactement un retour a la ligne par
ligne (et j'en suis maintenant a utiliser open my $f, '<:crlf', $name
de facon assez systematique lorsque je dois traiter des fichiers de
provenance douteuse, pour les memes raisons).

Apres, il y a le 1% de cas ou je dois reflechir a ce que je fais
lorsque je traite mon fichier...

mais je commence systematiquement par un chomp, et apres je reflechis...
et je ne l'enleve jamais si il s'avere etre juste inutile et non nuisible.

Ca me permet de passer plus de temps a reflechir aux aspects vraiment
interessants de mon programme...



Avatar
Paul Gaborit
À (at) Mon, 4 Dec 2006 11:54:37 +0000 (UTC),
(Marc Espie) écrivait (wrote):
Hum, je suis d'accord avec toi techniquement, mais pas sur le plan
du style.
[...]

mais je commence systematiquement par un chomp, et apres je reflechis...
et je ne l'enleve jamais si il s'avere etre juste inutile et non nuisible.


Tout à fait d'accord. Mais, à toute règle, il y a toujours des
exceptions (cette règle est sa propre exception ;-)).

La demande du PO consistait à optimiser son code. Dans ce cadre, la
suppression de l'appel à 'chomp', s'il est inutile, est une bonne
chose.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
kurtz_le_pirate
"Paul Gaborit" a écrit dans le message
de news:

À (at) Sat, 02 Dec 2006 17:54:55 +0100,
kurtz le pirate écrivait (wrote):
j'ai modifié mon script avec ces nouvelles idées et fais des tests
sur
un fichier un peu plus gros : 280Mo.
[... premier script...]

s'execute en 53". l'utilsation de la mémoire reste constante.
[...deuxième script...]

se plante à environ 50% du traitement avec un "not enough memory"!


Ça m'étonne beaucoup. Le script tel quel n'a aucune raison de
conserver des choses en mémoire.


justement moi aussi :((



je pensais que les deux substitutions étaient gourmandes en 'temps'
pas
en mémoire qu'apparemment, elles ne libèrent pas !


Est-ce vraiment la seule chose qu'il y a dans le script ?
Sur quelle version de Perl ?


perl est en version 5.8.8 et le script ne contient rien d'autres,
d'ailleurs le voila en entier :
---------------------------------------------------------------------------
#!/usr/bin/perl -w
use strict;
use Time::HiRes qw(gettimeofday tv_interval);

my $beginTime = [gettimeofday];
printf "Running Perl v%vd...n", $^V;

my $sourceFile = "evaperf_as_5.txt";
my $resultFile = "R_".$sourceFile;
my ($date,$val1,$val2,$val3);

open (SOURCEFILE,"<",$sourceFile)
or die "nerror when openning $sourceFile -> $!n";

open (RESULTFILE,">",$resultFile)
or die "nerror when openning $resultFile -> $!n";

my $count=0;
while (<SOURCEFILE>) {
next if $.%3 != 2;
tr/,./-,/;
(undef,$val1,$val2,undef) = split /-/;
print RESULTFILE "$countt$val1t$val2n";
$count++;
}
close RESULTFILE;
close SOURCEFILE;

my $endTime = [gettimeofday];
printf "...take %.2f seconds of cpu.nn",(tv_interval $beginTime,
$endTime);
---------------------------------------------------------------------------

--
klp