|
| Hvorfor er references ikke hurtigst? Fra : Morten Brix Pedersen |
Dato : 04-12-01 02:05 |
|
Hej,
Jeg har et program som laver en del parsing af en kæmpe txt fil, blandt
andet ved hjælp af regular expressions. jeg vil gerne gerne gøre det
lidt hurtigere, så jeg tænkte at references var svaret på mine bønder,
men mine tests viser noget andet:
#!/usr/bin/perl -w
use Benchmark qw(cmpthese);
$test = "hello\026 world hello\001 world!\026 WORLD hello\003 !\n";
cmpthese(-100,
{
references => sub {
sub remove1 {
my $str = shift;
$$str =~ s/world//g;
$$str =~ s/[\002\017\026\037]//g;
}
remove1(\$test);
},
no_ref => sub {
sub remove2 {
my $str = shift;
$str =~ s/world//g;
$str =~ s/[\002\017\026\037]//g;
return $str;
}
$test = remove2($test);
}
})
Den version der ikke bruger references, er 7 sekunder hurtigere, hvis
man sammenligner dem, hvor de begge kører i 100 sekunder:
Benchmark: running references, no_ref, each for at least 100 CPU seconds...
references: 117 wallclock secs (107.46 usr + 0.33 sys =
107.79 CPU) @ 156616.05/s (n=16881644)
no_ref: 110 wallclock secs (100.26 usr + -0.02 sys = 100.24
CPU) @ 131681.10/s (n=13199713)
Howcome?
- Morten.
| |
Thomas Martin Widman~ (04-12-2001)
| Kommentar Fra : Thomas Martin Widman~ |
Dato : 04-12-01 02:32 |
|
Morten Brix Pedersen <morten@wtf.dk> writes:
> Jeg har et program som laver en del parsing af en kæmpe txt fil,
> blandt andet ved hjælp af regular expressions. jeg vil gerne gerne
> gøre det lidt hurtigere, så jeg tænkte at references var svaret på
> mine bønder, men mine tests viser noget andet:
Den slags betyder kun noget, hvis man overfører store mængder data som
argument, fx et helt array. I dette tilfælde skal adressen på
variablen jo stadigvæk overføres (i begge tilfælde ét argument), og
til gengæld skal Perl så finde adressen på variablen og omvendt
bagefter.
> $$str =~ s/[\002\017\026\037]//g;
Når man vil slette tegn, kan man med fordel bruge tr (også kaldet y):
tr/\002\017\026\037//d; # utestet
/Thomas
--
cand.mag. Thomas Widmann Tlf.: +45/7028 4406
Universitetsparken 8, 2., -333 viralbus@daimi.au.dk
DK-8000 Århus C http://www.daimi.au.dk/~viralbus
| |
Thorbjoern Ravn Ande~ (04-12-2001)
| Kommentar Fra : Thorbjoern Ravn Ande~ |
Dato : 04-12-01 08:31 |
|
Morten Brix Pedersen <morten@wtf.dk> writes:
> Jeg har et program som laver en del parsing af en kæmpe txt fil, blandt
> andet ved hjælp af regular expressions. jeg vil gerne gerne gøre det
> lidt hurtigere, så jeg tænkte at references var svaret på mine bønder,
> men mine tests viser noget andet:
Hvis du finder den nuværende flaskehals i dit program, så har du et
meget bedre bud på hvad du skal sætte ind over for.
Har du flere detaljer?
--
Thorbjørn Ravn Andersen
http://unixsnedkeren.dk
| |
Morten Brix Pedersen (04-12-2001)
| Kommentar Fra : Morten Brix Pedersen |
Dato : 04-12-01 15:08 |
|
Thorbjoern Ravn Andersen wrote:
> Morten Brix Pedersen <morten@wtf.dk> writes:
>>Jeg har et program som laver en del parsing af en kæmpe txt fil, blandt
>>andet ved hjælp af regular expressions. jeg vil gerne gerne gøre det
>>lidt hurtigere, så jeg tænkte at references var svaret på mine bønder,
>>men mine tests viser noget andet:
>>
>
> Hvis du finder den nuværende flaskehals i dit program, så har du et
> meget bedre bud på hvad du skal sætte ind over for.
Mange bække små, gør en stor å.
Der er ikke en bestemt ting i programmet som gør at det er langsomt, det
er mange forskellige ting der tilsammen gør det langsomt, derfor prøver
jeg at få mere ud af hver enkel detalje.
> Har du flere detaljer?
Nej, desværre, scriptet i sig selv, er ret stort.
Jeg hentyder til http://pisg.sourceforge.net/ som er et script til at
parse IRC logfiler. Hvis du har lyst til at lede efter nogen ting som
kan forbedres, så kig i Logfile.pm i sub _parse_file().
Den indeholder en del regular expressions.
- Morten.
| |
Thorbjoern Ravn Ande~ (04-12-2001)
| Kommentar Fra : Thorbjoern Ravn Ande~ |
Dato : 04-12-01 15:37 |
|
Morten Brix Pedersen <morten@wtf.dk> writes:
> Thorbjoern Ravn Andersen wrote:
>
> > Morten Brix Pedersen <morten@wtf.dk> writes:
> >>Jeg har et program som laver en del parsing af en kæmpe txt fil, blandt
> >>andet ved hjælp af regular expressions. jeg vil gerne gerne gøre det
> >>lidt hurtigere, så jeg tænkte at references var svaret på mine bønder,
> >>men mine tests viser noget andet:
> >>
> >
> > Hvis du finder den nuværende flaskehals i dit program, så har du et
> > meget bedre bud på hvad du skal sætte ind over for.
>
>
> Mange bække små, gør en stor å.
>
> Der er ikke en bestemt ting i programmet som gør at det er langsomt, det
> er mange forskellige ting der tilsammen gør det langsomt, derfor prøver
> jeg at få mere ud af hver enkel detalje.
>
> > Har du flere detaljer?
>
>
> Nej, desværre, scriptet i sig selv, er ret stort.
>
> Jeg hentyder til http://pisg.sourceforge.net/ som er et script til at
> parse IRC logfiler. Hvis du har lyst til at lede efter nogen ting som
> kan forbedres, så kig i Logfile.pm i sub _parse_file().
Er det
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/~checkout~/pisg/pisg/modules/Pisg/Parser/Logfile.pm?rev=1.23&content-type=text/plain
du mener?
> Den indeholder en del regular expressions.
Og en hel del logik, hvor det er svaert at se hvor meget der sker
hvor. Hvor lang tid er for lang tid?
--
Thorbjørn Ravn Andersen
http://unixsnedkeren.dk
| |
Morten Brix Pedersen (04-12-2001)
| Kommentar Fra : Morten Brix Pedersen |
Dato : 04-12-01 16:00 |
|
Thorbjoern Ravn Andersen wrote:
> Morten Brix Pedersen <morten@wtf.dk> writes:
>>>Har du flere detaljer?
>>>
>>
>>Nej, desværre, scriptet i sig selv, er ret stort.
>>
>>Jeg hentyder til http://pisg.sourceforge.net/ som er et script til at
>>parse IRC logfiler. Hvis du har lyst til at lede efter nogen ting som
>>kan forbedres, så kig i Logfile.pm i sub _parse_file().
>>
>
> Er det
>
> http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/~checkout~/pisg/pisg/modules/Pisg/Parser/Logfile.pm?rev=1.23&content-type=text/plain
>
> du mener?
Nemlig.
>>Den indeholder en del regular expressions.
>>
>
> Og en hel del logik, hvor det er svaert at se hvor meget der sker
> hvor. Hvor lang tid er for lang tid?
"Alting er for lang tid", det store while loop køres på hver enkel linje
i loggen, og det kan godt være 100000+ linjer.
Det der bruger længst tid, er når man kommer ind i denne if sætning:
if ($hashref = $self->{parser}->normalline($line, $linecount)) {
Den gør det, at den kalder parsen for det specifikke logformat, og kører
nogen rutiner på den, via et format specifikt Perl modul, som ligger i
Format/mIRC.pm.
Den henter de forskellige værdier ud fra linjen i logfilen, og derefter
returnerer vi til Logfile.pm, hvor de forskellige værdier bruges til at
tælle en masse ting op. Blandt andet bliver der matches på smilies m.m.
Og der bliver talt ord op i _parse_words().
Håber det hjælper på forståelsen af koden.
- Morten.
| |
Thorbjørn Ravn Ander~ (05-12-2001)
| Kommentar Fra : Thorbjørn Ravn Ander~ |
Dato : 05-12-01 02:37 |
|
Morten Brix Pedersen wrote:
> Det der bruger længst tid, er når man kommer ind i denne if sætning:
> if ($hashref = $self->{parser}->normalline($line, $linecount)) {
Hvordan har du afgjort det?
> Den gør det, at den kalder parsen for det specifikke logformat, og kører
> nogen rutiner på den, via et format specifikt Perl modul, som ligger i
> Format/mIRC.pm.
>
> Den henter de forskellige værdier ud fra linjen i logfilen, og derefter
> returnerer vi til Logfile.pm, hvor de forskellige værdier bruges til at
> tælle en masse ting op. Blandt andet bliver der matches på smilies m.m.
> Og der bliver talt ord op i _parse_words().
>
> Håber det hjælper på forståelsen af koden.
Lidt, men det er stadig kun dig der kan analysere for at se hvor lang tid ting tager.
Du kunne eventuelt overveje hvad du gerne vil vide, og så fjerne det du ikke skal bruge.
| |
Morten Brix Pedersen (05-12-2001)
| Kommentar Fra : Morten Brix Pedersen |
Dato : 05-12-01 18:12 |
|
Thorbjørn Ravn Andersen wrote:
> Morten Brix Pedersen wrote:
>
>
>>Det der bruger længst tid, er når man kommer ind i denne if sætning:
>> if ($hashref = $self->{parser}->normalline($line, $linecount)) {
>>
>
> Hvordan har du afgjort det?
Den tungeste regular expression ligger der. Jeg har kørt scriptet
igennem Devel::DProf.
>>Den gør det, at den kalder parsen for det specifikke logformat, og kører
>>nogen rutiner på den, via et format specifikt Perl modul, som ligger i
>>Format/mIRC.pm.
>>
>>Den henter de forskellige værdier ud fra linjen i logfilen, og derefter
>>returnerer vi til Logfile.pm, hvor de forskellige værdier bruges til at
>>tælle en masse ting op. Blandt andet bliver der matches på smilies m.m.
>>Og der bliver talt ord op i _parse_words().
>>
>>Håber det hjælper på forståelsen af koden.
>>
>
> Lidt, men det er stadig kun dig der kan analysere for at se hvor lang tid ting tager.
Helt sikkert, men jeg leder efter generelle metoder til at gøre tingene
på en hurtigere og mere effektiv måde. Jeg er ligeglad hvor meget tid de
enkelte tager, bare om de enkelte ting kan gøres hurtigere.
> Du kunne eventuelt overveje hvad du gerne vil vide, og så fjerne det du ikke skal bruge.
Jeg skal bruge det hele
- Morten.
| |
Thorbjørn Ravn Ander~ (05-12-2001)
| Kommentar Fra : Thorbjørn Ravn Ander~ |
Dato : 05-12-01 23:39 |
|
Morten Brix Pedersen <morten@wtf.dk> writes:
> Helt sikkert, men jeg leder efter generelle metoder til at gøre tingene
> på en hurtigere og mere effektiv måde. Jeg er ligeglad hvor meget tid de
> enkelte tager, bare om de enkelte ting kan gøres hurtigere.
Så skal du ikke rode med referencer. Referencer betyder et ekstra lag
hver gang du skal have fat i noget indhold ("følge en pointer"),
hvilket kun er en fordel i visse situationer, fx når man jonglerer med
store array og lignende.
Eftersom at alt hvad der har med objektorienterethed ( -> operatoren)
følger referencer, vil dette pr defintiion være sløvere end
ikke-objektorienteret.
Hvis normalline trækker tænder ud, så var det et meget fornuftigt sted
at undersøge hvad det er der sløver mest dér. Omgrupperer
if-sætninger, håndoptimere regexps (der er en side om hvad der er
hurtigst men den kan jeg ikke lige hitte nu), og så'n.
--
Thorbjørn Ravn Andersen
http://unixsnedkeren.dk
| |
|
|