|
| En anden petitesse: strchr() eller flere i~ Fra : Bertel Lund Hansen |
Dato : 06-08-03 11:22 |
|
Hej alle
Hvad er bedst:
while (strchr("\"<>",*pos)) ++pos;
eller
if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
Det kan lyde som et petitessespørgsmål, og det er det også, men
det drejer sig om hvilken vane jeg skal tillægge mig eller
beholde.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Kent Friis (06-08-2003)
| Kommentar Fra : Kent Friis |
Dato : 06-08-03 12:22 |
|
Den Wed, 06 Aug 2003 12:21:46 +0200 skrev Bertel Lund Hansen:
>Hej alle
>
>Hvad er bedst:
>
> while (strchr("\"<>",*pos)) ++pos;
>
>eller
>
> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
>
>Det kan lyde som et petitessespørgsmål, og det er det også, men
>det drejer sig om hvilken vane jeg skal tillægge mig eller
>beholde.
Hvis du nu du er igang laver en
#define SEPARATORS "\"<>"
og så bruger den, så er programmet nemmere at udvide den dag du får
brug for to mere.
(Så kan du selv regne ud hvilken løsning der virker bedst med det
forslag).
Mvh
Kent
--
IE is the only thing capable of making Netscape look good
- D. Spider in comp.os.linux.advocacy
| |
Bertel Lund Hansen (06-08-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 06-08-03 13:03 |
|
Kent Friis skrev:
>Hvis du nu du er igang laver en
>#define SEPARATORS "\"<>"
Klart nok, dem har jeg mange af, denne her havde jeg blot
overset.
>(Så kan du selv regne ud hvilken løsning der virker bedst med det
>forslag).
Tænke, tænke ...
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Jens Axel Søgaard (06-08-2003)
| Kommentar Fra : Jens Axel Søgaard |
Dato : 06-08-03 13:55 |
|
Kent Friis wrote:
> Den Wed, 06 Aug 2003 12:21:46 +0200 skrev Bertel Lund Hansen:
>
>>Hej alle
>>
>>Hvad er bedst:
>>
>> while (strchr("\"<>",*pos)) ++pos;
>>
>>eller
>>
>> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
>>
>>Det kan lyde som et petitessespørgsmål, og det er det også, men
>>det drejer sig om hvilken vane jeg skal tillægge mig eller
>>beholde.
>
>
> Hvis du nu du er igang laver en
>
> #define SEPARATORS "\"<>"
>
> og så bruger den, så er programmet nemmere at udvide den dag du får
> brug for to mere.
Hvorfor ikke tage skridtet fuldt ud og lave en makro,
så man kan se hvad der sker:
#define SEPARATORS "\"<>"
/* SKIP_SEPATORS( char *pos )
Increase pos until *pos is a char not in SEPARATORS
*/
#define SKIP_SEPARATORS(pos) (strchr((SEPARATORS),*(pos))) ++(pos)
...
SKIP_SEPARATORS(pos);
...
(ikke testet)
--
Jens Axel Søgaard
| |
Igor V. Rafienko (06-08-2003)
| Kommentar Fra : Igor V. Rafienko |
Dato : 06-08-03 14:05 |
|
[ usenet@jasoegaard.dk ]
[ ... ]
> Hvorfor ikke tage skridtet fuldt ud og lave en makro, (...)
Helt fantastisk. _Flere_ gode forslag?
ivr, d'uh!
--
<html><form><input type crash></form></html>
| |
Soeren Sandmann (06-08-2003)
| Kommentar Fra : Soeren Sandmann |
Dato : 06-08-03 17:07 |
|
Bertel Lund Hansen <nospamfor@lundhansen.dk> writes:
> while (strchr("\"<>",*pos)) ++pos;
>
> eller
>
> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
Den sidste variant er betydeligt mere læselig end den første. Det er
muligvis en vanesag, men jeg var nødt til at studere den første
variant mere end én gang før det gik op for mig hvordan den virkede.
Det er ret usædvanligt at benytte strchr() til at søge efter variable
tegn i en konstant streng.
| |
Kent Friis (06-08-2003)
| Kommentar Fra : Kent Friis |
Dato : 06-08-03 18:11 |
|
Den 06 Aug 2003 18:06:45 +0200 skrev Soeren Sandmann:
>Bertel Lund Hansen <nospamfor@lundhansen.dk> writes:
>
>> while (strchr("\"<>",*pos)) ++pos;
>>
>> eller
>>
>> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
>
>Den sidste variant er betydeligt mere læselig end den første. Det er
>muligvis en vanesag, men jeg var nødt til at studere den første
>variant mere end én gang før det gik op for mig hvordan den virkede.
>Det er ret usædvanligt at benytte strchr() til at søge efter variable
>tegn i en konstant streng.
Det har jeg brugt mange gange.
Når antallet af konstante tegn er fx. 25, så er det absolut den nemmeste
måde.
Mvh
Kent
--
Indlæringskurven til Linux er stejl, til tider lodret... Men for katten
hvor er udsigten på toppen dog fantastisk
- Michael G. Vendelbo i dk.snak
| |
Bertel Lund Hansen (06-08-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 06-08-03 18:23 |
|
Soeren Sandmann skrev:
1)
>> while (strchr("\"<>",*pos)) ++pos;
>> eller
2)
>> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
>Den sidste variant er betydeligt mere læselig end den første. Det er
>muligvis en vanesag, men jeg var nødt til at studere den første
>variant mere end én gang før det gik op for mig hvordan den virkede.
>Det er ret usædvanligt at benytte strchr() til at søge efter variable
>tegn i en konstant streng.
Hm. Jeg har mine programmeringsvaner fra mig selv, men den metode
forekommer mig ganske logisk. Nu blev jeg imidlertid nødt til at
teste det, og det overraskede mig. En mio. kørsler med to
forskellige rutiner gav:
1): 5'500
2): 1'733
Strengen var lang, men der blev kun tjekket med 3 tegn. Med tjek
med 17 tegn:
1) 19'897
2) 2'950
Tyder det ikke på at strchr() er en dyr funktion?
Og jeg der synes at 1) er meget nemmere at læse ...
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Soeren Sandmann (06-08-2003)
| Kommentar Fra : Soeren Sandmann |
Dato : 06-08-03 19:34 |
|
Bertel Lund Hansen <nospamfor@lundhansen.dk> writes:
> Tyder det ikke på at strchr() er en dyr funktion?
Grunden til at jeg anbefalede 2) er at jeg synes det er lettere at
læse, ikke at det er hurtigere.
At det er hurtigere, er naturligvis rart nok, men hvis hastighed er
målet, så er mikrooptimeringer af denne type nærmest ubrugelige,
medmindre du har målt at programmet bruger meget tid lige netop her.
Det er i hvert fald en dårlig vane at vælge noget der er mindre
læseligt frem for noget man tror er mere effektivt (af de grunde som
alle kender til hudløshed).
Hvorfor er strchr() dyrere? Der kan være alle mulige grunde:
- strchr() læser fra hukommelsen, mens if-konstruktionen kun
sammenligner indholdet af et register med konstanter
- der er overhead forbundet med funktionskaldet
- oversætteren kan ikke optimere hen over funktionskald
- find selv på flere.
Ekstraopgave for hurtige elever: Find på grunde til at strchr() kan
være hurtigere end en stor if-konstruktion.
> Og jeg der synes at 1) er meget nemmere at læse ...
Så brug 1). Det er i hvert fald rigtigt nok, som Kent Friis skrev, at
metode 1) skalerer bedre til mange af hinanden uafhængige tegn.
| |
Niels Dybdahl (06-08-2003)
| Kommentar Fra : Niels Dybdahl |
Dato : 06-08-03 18:45 |
|
> Hvad er bedst:
>
> while (strchr("\"<>",*pos)) ++pos;
>
> eller
>
> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
strchr udgaven indeholder et funktionskald som koster en del. Nogle
compilere laver en inline udgave af strchr, hvilket eliminerer
funktionskaldet. Men stadig består strchr af et loop gennem tegnene, mens
den anden er et 'udfoldet' loop, hvilket er hurtigere end det tilsvarende
loop.
strchr udgaven vil ofte indeholde 1-6 jumps, calls og returns per chara, som
alle kan flushe pipelinen, mens den anden indeholder 1-2 jumps.
Den anden udgave kunne implementeres af compileren som tabelopslag, hvilket
ville være endnu hurtigere. Det er nok ikke sandsynligt at compileren gør
det ved 3 værdier, men ved mange kunne det være en mulighed.
Så nummer 2 er hurtigere og mere letlæselig.
Niels Dybdahl.
| |
Christian Larsen (06-08-2003)
| Kommentar Fra : Christian Larsen |
Dato : 06-08-03 19:00 |
|
Bertel Lund Hansen <nospamfor@lundhansen.dk> wrote in
news:tgl1jvkqk0vfbpsdtkng6cpal1s7jtifmu@news.stofanet.dk:
> Hej alle
>
> Hvad er bedst:
>
> while (strchr("\"<>",*pos)) ++pos;
>
> eller
>
> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
>
Jeg ved ikke om det har nogen relevans, men så vidt jeg kan se, giver de
to linjer ikke samme resultat. Den første skip'er en sekvens bestående
af et eller flere af tegnene, mens den anden blot skip'er ét tegn. Det
kunne selvfølgelig ændres ved at udskifte if/while.
-Christian
| |
Bertel Lund Hansen (06-08-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 06-08-03 20:16 |
| | |
Martin M. Pedersen (11-08-2003)
| Kommentar Fra : Martin M. Pedersen |
Dato : 11-08-03 17:21 |
|
Hej,
"Bertel Lund Hansen" <nospamfor@lundhansen.dk> wrote in message
news:tgl1jvkqk0vfbpsdtkng6cpal1s7jtifmu@news.stofanet.dk...
> while (strchr("\"<>",*pos)) ++pos;
> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
Vær opmærksom på at de to ikke ækvivalente. strchr() inkluderer også det
afsluttende '\0' i strengen den søger i, og løkken kan således køre henover
terminatoren i en NUL termineret streng.
mvh.
Martin
| |
Bertel Lund Hansen (11-08-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 11-08-03 22:05 |
|
Martin M. Pedersen skrev:
>> while (strchr("\"<>",*pos)) ++pos;
>> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
>Vær opmærksom på at de to ikke ækvivalente. strchr() inkluderer også det
>afsluttende '\0' i strengen den søger i, og løkken kan således køre henover
>terminatoren i en NUL termineret streng.
Hvis du havde ret, skulle den øverste linje scanne hele
computerens hukommelse hver gang. Desuden passer det dårligt med
at strchr() skal returnere NULL hvis tegnet ikke findes i
strengen.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Martin M. Pedersen (11-08-2003)
| Kommentar Fra : Martin M. Pedersen |
Dato : 11-08-03 22:22 |
|
"Bertel Lund Hansen" <nospamfor@lundhansen.dk> wrote in message
news:511gjvkg5qq1cordlct67lp86k2hmqkj2k@news.stofanet.dk...
> Martin M. Pedersen skrev:
>
> >> while (strchr("\"<>",*pos)) ++pos;
> >> if (*pos=='\"' || *pos=='<' || *pos=='>') ++pos;
>
> >Vær opmærksom på at de to ikke ækvivalente. strchr() inkluderer også det
> >afsluttende '\0' i strengen den søger i, og løkken kan således køre
henover
> >terminatoren i en NUL termineret streng.
>
> Hvis du havde ret, skulle den øverste linje scanne hele
> computerens hukommelse hver gang. Desuden passer det dårligt med
> at strchr() skal returnere NULL hvis tegnet ikke findes i
> strengen.
Nej, det sidste '\0' betragtes blot som en del af strengen. Hvis jeg for
eksempel kører dette:
#include <stdio.h>
int main(void)
{
printf("%p\n", strchr("abc", '\0'));
return 0;
}
får jeg: "0x8048407" - dvs. at den har fundet '\0'. Det er også i
standarden. Dette er fra den sidste draft af C99 (men det er ikke ny
opførsel):
7.21.5.2 The strchr function
Synopsis
#include <string.h>
char *strchr(const char *s, int c);
Description
The strchr function locates the first occurrence of c (converted to a
char)
in the string pointed to by s. The terminating null character is
considered
to be part of the string.
Returns
The strchr function returns a pointer to the located character, or a
null
pointer if the character does not occur in the string.
mvh.
Martin
| |
Bertel Lund Hansen (11-08-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 11-08-03 23:32 |
|
Martin M. Pedersen skrev:
>Nej, det sidste '\0' betragtes blot som en del af strengen.
Ja, naturligvis.
Men du skrev før:
>løkken kan således køre henover terminatoren i en NUL termineret streng.
Det kan den bare ikke.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Martin M. Pedersen (11-08-2003)
| Kommentar Fra : Martin M. Pedersen |
Dato : 11-08-03 23:48 |
|
"Bertel Lund Hansen" <nospamfor@lundhansen.dk> wrote in message
news:bs5gjvcceig6p5v075k3bltb5svg40a5l1@news.stofanet.dk...
> >løkken kan således køre henover terminatoren i en NUL termineret streng.
> Det kan den bare ikke.
Sagtens. Prøv dette:
#include <stdio.h>
int main(void)
{
static const char str[] = "\"\"<<>>\0\0\0>>h";
const char* pos = str;
while (strchr("\"<>",*pos)) ++pos;
printf("*pos = %c (%d)\n", *pos, *pos);
}
Den kører naturligvis henover '\0'erne og finder h'et.
mvh.
Martin
| |
Bertel Lund Hansen (12-08-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 12-08-03 09:07 |
| | |
Martin M. Pedersen (12-08-2003)
| Kommentar Fra : Martin M. Pedersen |
Dato : 12-08-03 15:35 |
|
"Bertel Lund Hansen" <nospamfor@lundhansen.dk> wrote in message
news:8v7hjvcnkdb36coochielvndqn0gmv85s2@news.stofanet.dk...
> Martin M. Pedersen skrev:
>
> >Den kører naturligvis henover '\0'erne og finder h'et.
>
> Nu var der lissom ikke noget \0 i den linje som din påstand
> handlede om.
Nå, jeg synes ellers det udemærket illustrerer at løkken kører hen over
NUL'er. Jeg prøver igen. Min påstand var "løkken kan således køre henover
terminatoren i en NUL termineret streng.", hvilket også dette program
illustrer:
===============
#include <stdio.h>
int main(void)
{
static const char str[] = "<<>>";
const char *pos = str;
while (strchr("\"<>",*pos)) ++pos;
printf("str=%p pos=%p skipped=%d\n", str, pos, pos-str);
return 0;
}
===============
Hos mig skriver den tilfældigvis "str=0x8048424 pos=0x804842d skipped=9",
men i princippet kunne programmet lige så godt dø af en segmentation fault
eller lignende.
mvh.
Martin
| |
Bertel Lund Hansen (12-08-2003)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 12-08-03 16:06 |
|
Martin M. Pedersen skrev:
>NUL'er. Jeg prøver igen. Min påstand var "løkken kan således køre henover
>terminatoren i en NUL termineret streng.", hvilket også dette program
>illustrer:
Du har ganske ret, og jeg er overrasket. Det er sikkert derfor at
den løsning er meget langsommere end sammenligningen ét tegn ad
gangen.
Min løsning i programmet blev imidlertid at lave en makro baseret
på den hurtige metode, så jeg har allerede undgået problemet.
Tak for hjælpen.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
|
|