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

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Et simpel spørgsmål (primært operator prec~
Fra : Thomas Schulz


Dato : 27-12-01 10:55

Her et noget simpel C++ taget fra
"Accelerated C++" (side 177):

size_t strlen(const char* p) {
size_t size = 0;
while (*p++ != '\0')
++size;
return size;
}


mit problem er *p++

Jeg kigger nemlig på side 120+121 fra "The C++ Programming Language -
special edition" (vist nok 3rd) af Bjarne Stroustrup.

Den siger * har mindre precedence end ++ (post)
Det vil jo sige at den først flytter "p" hen på næste element - og så
derefererer den.. Hvis det er sandt får den forkert size..
Fx 'hello\0' = er 5 chars langs, men resultatet vil blive 4.
For at overbevise sig om det kan man bare tage et kort ord, fx 'i\0' på et
bogstav.

Og så giver det jo ikke rigtigt mening. Jeg mener at left/right associativ
kun gælder i sammenhæng med andre af samme precedence?
Kan nogen forklare logikken. Hvis Bjarne har ret burde den kode fra
Accelerated C++ ikke virke (sådan som jeg forstår det).


Jeg har helt klart misforstået noget, men hvad?


Thomas



 
 
Ulrik Magnusson (27-12-2001)
Kommentar
Fra : Ulrik Magnusson


Dato : 27-12-01 11:19



Thomas Schulz wrote:

> Her et noget simpel C++ taget fra
> "Accelerated C++" (side 177):
>
> size_t strlen(const char* p) {
> size_t size = 0;
> while (*p++ != '\0')
> ++size;
> return size;
> }
>
> mit problem er *p++
>
> Jeg kigger nemlig på side 120+121 fra "The C++ Programming Language -
> special edition" (vist nok 3rd) af Bjarne Stroustrup.
>
> Den siger * har mindre precedence end ++ (post)
> Det vil jo sige at den først flytter "p" hen på næste element - og så
> derefererer den.. Hvis det er sandt får den forkert size..

Der er jo forskel på p++ og ++p - i første tilfælde vil den inkrementerede
version først dukke op næste gang p bruges.

int n = 0;
int n1 = n++; // n1 bliver 0
int n2 = ++n; // n2 bliver 2

> Fx 'hello\0' = er 5 chars langs, men resultatet vil blive 4.
> For at overbevise sig om det kan man bare tage et kort ord, fx 'i\0' på et
> bogstav.

Lad os gøre det:

strlen( 'i\0' )
size_t size = 0;
'i' != '\0' så ++size;
'\0' == '\0' så size bliver 1

Ulrik Magnusson


Thomas Schulz (31-12-2001)
Kommentar
Fra : Thomas Schulz


Dato : 31-12-01 12:55

> Der er jo forskel på p++ og ++p - i første tilfælde vil den inkrementerede
> version først dukke op næste gang p bruges.

Ville også bare lige huske at sige tak til dig.

Godt nytår alle (til dem som læser denne besked :)

mvh
Thomas Schulz



Soeren Sandmann (27-12-2001)
Kommentar
Fra : Soeren Sandmann


Dato : 27-12-01 11:26

"Thomas Schulz" <dk_sz@hotmail.com> writes:

> Det vil jo sige at den først flytter "p" hen på næste element - og så
> derefererer den.. Hvis det er sandt får den forkert size..

Det du overser, er at værdien af udtrykket p++ er p. Præcedensreglerne
betyder bare at udtrykket skal forstås som

*(p++),

ikke som

(*p)++.

Ud over at give resultatet p bevirker p++ også at p tælles op med én,
så hele udtrykket har sideeffekten at p bliver talt op med én.

Bertel Lund Hansen (27-12-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 27-12-01 11:51

Soeren Sandmann skrev:

>Det du overser, er at værdien af udtrykket p++ er p. Præcedensreglerne
>betyder bare at udtrykket skal forstås som

> *(p++),

Jeg har vænnet mig til at skrive den slags udtryk med paranteser,
og jeg spekulerer ikke på om de er nødvendige eller ej.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Thomas Schulz (27-12-2001)
Kommentar
Fra : Thomas Schulz


Dato : 27-12-01 12:32

> Det du overser, er at værdien af udtrykket p++ er p. Præcedensreglerne
> betyder bare at udtrykket skal forstås som

ahhhhhhhh ja
jeg troede (tænkte på det) det som værende p+1
nu giver det hele mening


Jeg burde selv have tænkt det,
men ak,
jeg har kun tilbage at sige,
mange tak!


okay, rim og digte har aldrig lige været det som.. :)


Thomas



Claus Rasmussen (27-12-2001)
Kommentar
Fra : Claus Rasmussen


Dato : 27-12-01 19:22

Thomas Schulz wrote:

> Jeg burde selv have tænkt det,
> men ak,
> jeg har kun tilbage at sige,
> mange tak!
>
> okay, rim og digte har aldrig lige været det som.. :)

Som det første takke-rim i d.e.p.c er det nu ganske godt gået

-Claus


Per Abrahamsen (28-12-2001)
Kommentar
Fra : Per Abrahamsen


Dato : 28-12-01 15:08

Bertel Lund Hansen <nospam@lundhansen.dk> writes:

> Soeren Sandmann skrev:
>
>> *(p++),
>
> Jeg har vænnet mig til at skrive den slags udtryk med paranteser,
> og jeg spekulerer ikke på om de er nødvendige eller ej.

Jeg skriver slet ikke den slags udtryk, hverken med eller uden
parenteser.

Jeg kan generelt bedst lide hvis et udtryk enten har en sideeffekt
eller en værdi, men ikke begge ting på en gang.


Ostehapsen (27-12-2001)
Kommentar
Fra : Ostehapsen


Dato : 27-12-01 22:07

Per Abrahamsen wrote:

> Bertel Lund Hansen <nospam@lundhansen.dk> writes:
>
>
>>Soeren Sandmann skrev:
>>
>>
>>> *(p++),
>>>
>>Jeg har vænnet mig til at skrive den slags udtryk med paranteser,
>>og jeg spekulerer ikke på om de er nødvendige eller ej.
>>


Det er et spørgsmål om smag og det kan ikke diskuteres (jeg hader alle
de overflødige paranteser :) )

>
> Jeg skriver slet ikke den slags udtryk, hverken med eller uden
> parenteser.
>
> Jeg kan generelt bedst lide hvis et udtryk enten har en sideeffekt
> eller en værdi, men ikke begge ting på en gang.


Jeg studser over betegnelsen "sideeffekt". Du kan ikke lide p++? p
tælles op og værdien af udtrykket er p hvad enten du skal bruge den
eller ej, så deeet...

Hvis der er behov for performance så er det værd at overveje om der kan
være en performance-fordel i at skrive *p++ eller om behovet for "klar
kode" vejer tungere.

I forbindelse med klasser i C++ kan der være en performance-fordel i at
bruge prefix ++ (eller --) operator fremfor postfix (postfix operatoren
skrives typisk ud fra prefix operatoren).


Bertel Lund Hansen (29-12-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 29-12-01 00:17

Ostehapsen skrev:

>Hvis der er behov for performance så er det værd at overveje om der kan
>være en performance-fordel i at skrive *p++ eller om behovet for "klar
>kode" vejer tungere.

Det kræver et ret intimt kendskab til compileren at afgøre om det
ene er bedre end det andet - eller mange tidsstudier.

Jeg har brugt lang tid på at time forskellige operationer - på
CBM64 under Comal og Basic. Der går måneder (år?) imellem at jeg
gider nu. Den kode der er skrevet klart, sparer ofte *mange*
gange de mikrosekunder som en tweaket kode kører hurtigere. Det
gælder både 'personlige' og professionelle programmer.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Claus Rasmussen (29-12-2001)
Kommentar
Fra : Claus Rasmussen


Dato : 29-12-01 00:45

Bertel Lund Hansen wrote:

> Ostehapsen skrev:
>
>>Hvis der er behov for performance så er det værd at overveje om der kan
>>være en performance-fordel i at skrive *p++ eller om behovet for "klar
>>kode" vejer tungere.
>
> Det kræver et ret intimt kendskab til compileren at afgøre om det
> ene er bedre end det andet - eller mange tidsstudier.

Faktisk er reglen, at man bør afholde sig fra optimeringer på det niveau.
Kompilerteknologien er i dag så udviklet, at det er meget svært at nå
bedre resultater ved at gøre det selv.

I stedet bør man vurdere, hvad der er lettest at læse. Men det er jo
temmeligt subjektivt: Jeg foretrækker konstruktioner som (*p++ = *q++)
men det er kun fordi, jeg er vant til at se dem. Andre ville foretrække
det skrevet ud i et for-loop.

-Claus



Ostehapsen (28-12-2001)
Kommentar
Fra : Ostehapsen


Dato : 28-12-01 09:39

Claus Rasmussen wrote:

> Bertel Lund Hansen wrote:
>>Det kræver et ret intimt kendskab til compileren at afgøre om det
>>ene er bedre end det andet - eller mange tidsstudier.


> Faktisk er reglen, at man bør afholde sig fra optimeringer på det niveau.


Jeg er usikker på hvad du mener med "det niveau",

men jeg tror ikke at jeg er enig :) (og jeg har aldrig hørt om den regel)

Hvis en ud af fem maskinkodeoperationer i en tæt løkke kan spares uden at

rode med maskinkode, så er det vel værd at tage med?


> Kompilerteknologien er i dag så udviklet, at det er meget svært at nå
> bedre resultater ved at gøre det selv.


Når det gælder kompilatorer til PC-programmer har du givetvis ret.
Dertil kommer at der sjældent er det store behov for optimering i
PC-programmer.

Behovet er nok større i indlejrede systemer med forholdsmæssigt
langsommere processorer og andre krav, og der findes mange obskure
kompilatorer til indlejrede systemer. Der skal nok være en eller to af
dem som ikke kan optimere nævneværdigt (og som er spækket med
underholdende fejl).

Kend dine behov, og som Bertel skriver: Kend din kompilator...

> I stedet bør man vurdere, hvad der er lettest at læse. Men det er jo
> temmeligt subjektivt: Jeg foretrækker konstruktioner som (*p++ = *q++)
> men det er kun fordi, jeg er vant til at se dem. Andre ville foretrække
> det skrevet ud i et for-loop.

Enig, ja, mange ville nok ovenikøbet foretrække at indeksere (a[t] =
b[t]) med deraf følgende performance hit (That was a good wending, maybe
we kan use that in another indlæg).


Igor V. Rafienko (29-12-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 29-12-01 14:33

[ blah@blah.dk ]

[ snip ]

> Enig, ja, mange ville nok ovenikøbet foretrække at indeksere (a[t] =
> b[t]) med deraf følgende performance hit


Hvis en kompilator ikke er istand til å generere identisk kode for:

while ( *d++ = *s++ )
;

og

ssize_t i = -1;
do {
++i;
dst[i] = src[i];
} while ( dst[i] != '\0' );


så er _kompilatoren_ seriøst defekt og den _eneste_ mulige
framgangsmåten er å bytte den. Det er _ingen_ performance hit ved å
bruke op[] i forhold til op*() (forresten den første varianten bruker
en instruksjon mer på SPARC og IA32 med gcc-2.95.2. Sun Forte 6
genererer de samme instruksjonene (dog, i en annen rekkefølge)).

[ snip ]





ivr
--
Ehh... I'll have a McRudolf menu, please.

N/A (30-12-2001)
Kommentar
Fra : N/A


Dato : 30-12-01 13:50



Bertel Lund Hansen (30-12-2001)
Kommentar
Fra : Bertel Lund Hansen


Dato : 30-12-01 13:50

Claus Rasmussen skrev:

>Jeg har også vedlagt et (linux) shell script, der måler tidsforbruget for
>de tre versioner. Når man kører det, får man flg. resultat (i 1/100s):

> Straight version : 335
> Optimized version : 343
> Extra optimized version: 341

Meget smukt eksempel.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Ostehapsen (28-12-2001)
Kommentar
Fra : Ostehapsen


Dato : 28-12-01 09:19

Bertel Lund Hansen wrote:

> Ostehapsen skrev:
>
>
>>Hvis der er behov for performance så er det værd at overveje om der kan
>>være en performance-fordel i at skrive *p++ eller om behovet for "klar
>>kode" vejer tungere.
>>


> Den kode der er skrevet klart, sparer ofte *mange*
> gange de mikrosekunder som en tweaket kode kører hurtigere. Det
> gælder både 'personlige' og professionelle programmer.

Jeg er slet ikke uenig. Man bør kende konsekvenserne ved at foretrække
en skrivemåde fremfor en anden. Desværre (eller heldigvis?) er der delte
meninger om hvad der er tweaket hhv. klar kode.

Som regel er andres kode altid noget #¤%& hø :)


Soeren Sandmann (29-12-2001)
Kommentar
Fra : Soeren Sandmann


Dato : 29-12-01 17:34

Bertel Lund Hansen <nospam@lundhansen.dk> writes:

> gider nu. Den kode der er skrevet klart, sparer ofte *mange*
> gange de mikrosekunder som en tweaket kode kører hurtigere. Det
> gælder både 'personlige' og professionelle programmer.

Enig, og faktisk vil jeg gå længere: Den kode som er skrevet klart er
(potentielt) mange gange hurtigere end kode som er tweaket. Det hænger
sammen med at hvis man bestemmer sig for at programmet skal være
hurtigere, så er det første man skal gøre at måle hvad programmet
bruger tiden til. Hvis programmet bruger k% af tiden i en bestemt
procedure, kan optimeringer i den procedure under ingen omstændigheder
forbedre programmets hastighed med mere end k%.

Når man har målt det (ikke gættet det - man gætter næsten altid galt),
vil man have stor gavn af det hvis koden er bygget op af moduler der
ikke ved ret meget om hinandens implementationsdetaljer. Det sikrer at
optimeringer i et enkelt modul ikke indvirker på de andre. Man vil
også have gavn af at koden er skrevet læseligt, så man kan forstå hvad
der foregår og optimere uden at introducere for mange fejl.

Desuden: Hvis det endelig viser sig at en bestemt mikrooptimering er
nødvendig, er det sikkert bedre at skrive det i assembler i stedet for
at forlade sig på at compileren genererer en bestemt sekvens af
operationer. Så er man sikker på at man får de instruktioner man vil
have, og man kommer ikke til at bilde sig selv ind at det man har
foretaget sig, er portabelt.

Jacob Bunk Nielsen (29-12-2001)
Kommentar
Fra : Jacob Bunk Nielsen


Dato : 29-12-01 13:47

Ostehapsen <blah@blah.dk> writes:

>> Faktisk er reglen, at man bør afholde sig fra optimeringer på det niveau.
>
> Jeg er usikker på hvad du mener med "det niveau", men jeg tror ikke at
> jeg er enig :)

Jeg tror at Claus mener at man skal holde sig fra at spare den ene
instruktion, hvis det forringer læsbarheden af koden.

I stedet kan man så give sig til at optimere sin algoritme, det får
man ofte meget mere ud af end at optimere de enkelte sætninger i
programmet.

> (og jeg har aldrig hørt om den regel) Hvis en ud af fem
> maskinkodeoperationer i en tæt løkke kan spares uden at rode med
> maskinkode, så er det vel værd at tage med?

IMHO ikke nødvendigvis. Hvis vi taler om en løkke der skal gennemløbes
*rigtig* mange gange, og det er et reelt problem at det kører for
langsomt.

Hvis det er en løkke der skal gennemløbes et begrænset antal gange,
eller det ikke udgør et performanceproblem, så vil jeg ikke ofre det
til fordel for læsbarheden af programmet.

--
Jacob - www.bunk.cc
I used to have a drinking problem. Now I love the stuff.

Per Abrahamsen (31-12-2001)
Kommentar
Fra : Per Abrahamsen


Dato : 31-12-01 16:10

Ostehapsen <blah@blah.dk> writes:

> Jeg studser over betegnelsen "sideeffekt". Du kan ikke lide p++?

Jo, men jeg bruger ikke værdien, kun sideeffekten. Med andre ord, jeg
bruger p++ som en statement, ikke en expression.

> Hvis der er behov for performance så er det værd at overveje om der
> kan være en performance-fordel i at skrive *p++ eller om behovet for
> "klar kode" vejer tungere.

Den slags mikrooptimeringer kan compileren næsten altid klare, så der
er sjældent værd at spekulere på.

> I forbindelse med klasser i C++ kan der være en performance-fordel i
> at bruge prefix ++ (eller --) operator fremfor postfix (postfix
> operatoren skrives typisk ud fra prefix operatoren).

Jeg ved det. Det sutter. Jeg synes postfix er pænere, og bruger
alligevel ikke værdien.

Søg
Reklame
Statistik
Spørgsmål : 177552
Tips : 31968
Nyheder : 719565
Indlæg : 6408847
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste