/ Forside / Teknologi / Udvikling / Perl / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Perl
#NavnPoint
bjarneA 141
poul_from 50
soccer 30
Nicknack 14
Tmpj 0
Itererer over tegnene i en streng
Fra : Peter Makholm


Dato : 27-03-07 14:03

For et stykke tid siden sad jeg og skrev på noget kode der skulle
parse nogle loglinjer. Jeg havde i forvejen to stykker kode, der ikke
virkede: en der brugte perl og regulære udtryk og en skrevet i C der itererede
over tegnene i linjen.

Den sidste var lettest at tilrette på en måde hvor det var klart hvad
der foregik. Men da jeg benchmarkede fandt jeg at uanset hvordan jeg
greb opgaven an, så var det væsentlig langsommere at iterere over
bogstaverne i strengen end det ikke specielt pæne regexp jeg havde
hacket sammen. Væsentligt langsommere var en faktor 8-10.

Er der nogen ide til hvordan man oversætter C-ideomet:

char *c, *p;
for(p = c;p;p++) {
/* Gør noget med p */
}

til noget perl der ikke stinker voldsomt?

//Makholm



 
 
Lars Balker Rasmusse~ (27-03-2007)
Kommentar
Fra : Lars Balker Rasmusse~


Dato : 27-03-07 14:06

Peter Makholm <peter@makholm.net> writes:
> Er der nogen ide til hvordan man oversætter C-ideomet:
>
> char *c, *p;
> for(p = c;p;p++) {
> /* Gør noget med p */
> }
>
> til noget perl der ikke stinker voldsomt?

Nej - den rigtige metode hænger voldsomt sammen med "Gør noget" og den
forventede længde af c.
--
Lars Balker Rasmussen

Thorbjørn Ravn Ander~ (27-03-2007)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 27-03-07 14:40

Peter Makholm <peter@makholm.net> writes:

> bogstaverne i strengen end det ikke specielt pæne regexp jeg havde

Hvorfor ikke bare smukkesere regexp'en? Bruger du /x?
--
Thorbjørn Ravn Andersen

Michael Zedeler (27-03-2007)
Kommentar
Fra : Michael Zedeler


Dato : 27-03-07 19:56

Peter Makholm skrev:
> For et stykke tid siden sad jeg og skrev på noget kode der skulle
> parse nogle loglinjer. Jeg havde i forvejen to stykker kode, der ikke
> virkede: en der brugte perl og regulære udtryk og en skrevet i C der itererede
> over tegnene i linjen.
>
> Den sidste var lettest at tilrette på en måde hvor det var klart hvad
> der foregik. Men da jeg benchmarkede fandt jeg at uanset hvordan jeg
> greb opgaven an, så var det væsentlig langsommere at iterere over
> bogstaverne i strengen end det ikke specielt pæne regexp jeg havde
> hacket sammen. Væsentligt langsommere var en faktor 8-10.
>
> Er der nogen ide til hvordan man oversætter C-ideomet:
>
> char *c, *p;
> for(p = c;p;p++) {
> /* Gør noget med p */
> }
>
> til noget perl der ikke stinker voldsomt?

First take ville være

foreach my $c (split //, $string) {
   ...
}

Men det bliver altså utrolig langsomt. En hurtig måling viser at perl
øjensynligt kan noget smartere med substr():

for($i=0; $i<1000000; $i++) {$a .= "a"}

real 0m1.372s
user 0m1.341s
sys 0m0.050s


for($i=0; $i<1000000; $i++) {$a .= "a"}
foreach my $char (split //, $a) { print $char, "\n"}

real 0m4.566s
user 0m3.955s
sys 0m0.220s

for($i=0; $i<1000000; $i++) {$a .= "a"}
for(my $i=0; $i<100000; $i++) { print substr($a,$i,1), "\n"}'

real 0m1.572s
user 0m1.552s
sys 0m0.030s

Så regner man initialiseringen af strengen fra, tager det blot 200ms at
kigge på resultatet fra substr(), frem for at bruge split. Det er en
reduktion i køretid til ca. 15%.

Om det så er brugbart for dig må jo komme an på en prøve.

Mvh. Michael.
--
Which is more dangerous? TV guided missiles or TV guided families?
I am less likely to answer usenet postings by anonymous authors.
Visit my home page at http://michael.zedeler.dk/

Flemming Frandsen (28-03-2007)
Kommentar
Fra : Flemming Frandsen


Dato : 28-03-07 12:05

Peter Makholm wrote:
> så var det væsentlig langsommere at iterere over
> bogstaverne i strengen end det ikke specielt pæne regexp jeg havde
> hacket sammen.

Sådan er det, regexps er drønhurtige, jeg vil foreslå at du lærer lidt
mere om regexps så du holder op med at mene at de er grimme...

Prøv en gang at poste et par loglinier og en beskrivelse af hvad du skal
bruge dem til, så er der nok nogen der kan skrive et pænt regexp:)

Peter Makholm (28-03-2007)
Kommentar
Fra : Peter Makholm


Dato : 28-03-07 13:38

Flemming Frandsen <ff-remove.the.last.invalid@partyticket.net.invalid>
writes:

> Sådan er det, regexps er drønhurtige, jeg vil foreslå at du lærer lidt
> mere om regexps så du holder op med at mene at de er grimme...

Ja, man kommer drønhurtigt til at lave noget med en katastrofal
køretid. Men efter jeg har fået elimineret behovet for at neste
parenteser (af forskellige slags), så er det værste jeg har tilbage
noget ala:

/<someregexp> "((?:.*?)(?<!\\)(?:\\\\)*)" <moreregexp>/

og det tror jeg umidelbart skulle være liniært i længden af
inputstrengen og så tror jeg ikke perls regexp-engine er så meget
langsomere end et stykke velskrevet C-kode.

Jeg synes stadigvæk det ville være rart også effektivt kunne gøre
noget i stil med:

$escaped = 0;
@chars = split //;
for (@chars) {
if ($escaped) {
$escaped = 0;
next;
}

last if /"/;
$escaped = 1 if /\\/;
}

Arbejder man med regulære udtryk mener jeg det kan være nødvendigt med
en sund skepsis. En holdning jeg kun finder bestyrket hver gang jeg
læser Jeffrey Friedls bog om emnet.

//Makholm

Flemming Frandsen (28-03-2007)
Kommentar
Fra : Flemming Frandsen


Dato : 28-03-07 13:53

Peter Makholm wrote:
> og det tror jeg umidelbart skulle være liniært i længden af
> inputstrengen og så tror jeg ikke perls regexp-engine er så meget
> langsomere end et stykke velskrevet C-kode.

Nøh, regexp enginen er vel også et stykke velskrevet C-kode :)


> Jeg synes stadigvæk det ville være rart også effektivt kunne gøre
> noget i stil med:

Jeg tror Wall en gang har sagt noget i stil med at hvis man har lyst til
at skrive i C så skal man skrive i C:)

Hvis det er noget der skal tæskes igennem tit så kunne noget embedded C
måske være at foretrække, hvis regexpet stadig er for langsomt?


> Arbejder man med regulære udtryk mener jeg det kan være nødvendigt med
> en sund skepsis. En holdning jeg kun finder bestyrket hver gang jeg
> læser Jeffrey Friedls bog om emnet.

Den har jeg ikke en gang læst, det kunne være jeg burde gøre det...

Peter Makholm (28-03-2007)
Kommentar
Fra : Peter Makholm


Dato : 28-03-07 15:33

Flemming Frandsen <ff-remove.the.last.invalid@partyticket.net.invalid>
writes:

> Peter Makholm wrote:
>> og det tror jeg umidelbart skulle være liniært i længden af
>> inputstrengen og så tror jeg ikke perls regexp-engine er så meget
>> langsomere end et stykke velskrevet C-kode.
>
> Nøh, regexp enginen er vel også et stykke velskrevet C-kode :)

Velskrevet til opgaven.

>> Jeg synes stadigvæk det ville være rart også effektivt kunne gøre
>> noget i stil med:
>
> Jeg tror Wall en gang har sagt noget i stil med at hvis man har lyst
> til at skrive i C så skal man skrive i C:)

Jeg har ikke lyst til at skrive i C, jeg har lyst til at skanne
liniært gennem en tekststreng.

> Hvis det er noget der skal tæskes igennem tit så kunne noget embedded
> C måske være at foretrække, hvis regexpet stadig er for langsomt?

Kun et to-cifret antal millioner gange i døgnet. Så det er et par
minutters cpu-tid det drejer sig om. Men eftersom jeg har fået omgået
behovet for reel backtracking er det ikke regexpet jeg bekymre mig om.


//Makholm

Thorbjørn Ravn Ander~ (28-03-2007)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 28-03-07 16:57

Peter Makholm <peter@makholm.net> writes:

> Kun et to-cifret antal millioner gange i døgnet. Så det er et par
> minutters cpu-tid det drejer sig om. Men eftersom jeg har fået
> omgået behovet for reel backtracking er det ikke regexpet jeg
> bekymre mig om.

Hvis du har seriøst brug for backtracking er du lige på vippet til at
være udover hvad regulære udtryk er beregnet til.

Måske er det et tidligere løst problem. Kunne du eventuelt skitsere
hvad det er du ønsker at gøre?

--
Thorbjørn Ravn Andersen

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste