Article View: be.comp.programming
Article #12527Re: C decrement / increment
From: Roel Schroeven
Date: Sat, 10 Nov 2001 13:25
Date: Sat, 10 Nov 2001 13:25
210 lines
7396 bytes
7396 bytes
Eerlijk gezegd begrijp ik je probleem niet helemaal hoor. Waarom niet
gewoon zoals in volgend fragment?
a[x] = c;
b[x] = d;
c[x] = e;
if (...)
c[x] = getal;
x++;
De x++ binnen c[x++] levert geen snelheidswinst op, moest je dat denken.
De compiler genereert in beide gevallen exact dezelfde code.
Iets sneller is:
...
if (! ...)
c[x] = e;
else
c[x] = getal;
x++;
In mijn eerste fragmentje wordt c[x] = e altijd uitgevoerd, ook als het niet
nodig is. In het tweede wordt dat alleen uitgevoerd als het nodig is,
maar het staat wel als 'default' geval voor de if omdat dat sneller is.
Nog een mogelijkheid:
c[x++] = (! <voorwaarde> ) ? e : getal;
In article <3beb3ad1.46039351@news.pandora.be>, "[EdGe]"
<olx09654@online.be> wrote:
> Huidige vorm is:
> c[x] = e;
> if (...) c[x] = getal;
> x++;
> Wat niet bij snelle code reviews de indruk wekt dat x 2* opgehoogd
> wordt.
Euh... wat bedoel je daar juist mee? De indruk die dat bij mij geeft is
dat x een keertje wordt opgehoogd, en uit voorgaande fragmenten lijkt dat
toch te zijn wat moet gebeuren?
> In principe zou het ook correct zijn als pre-decrement en post-increment
> samen gebruikt kunnen worden, maar mijn compiler vertikt dat. Omdat de
> uitzondering zelden voorkomt, zou dat in zeer snelle code geresulteerd
> kunnen hebben:
>
> if(...) c[--x++] =getal;
Reden waarom je compiler dit niet accepteert is al uitgelegd in een andere
posting. Maar het zou zelfs niet eens sneller zijn dan mijn voorstel.
Even detailleren wat jouw code zou doen, als het zou kunnen:
c[x++] = e;
/* - gebruik x als offset om het adres van c[x] te berekenen, */
/* en zet e op dat adres (dus eigenlijk gewoon c[x] = e) */
/* - increment x */
if (...)
/* jump naar adres na volgend fragmentje om het over te slaan */
/* als niet voldaan is na de voorwaarde */
c[--x++] = getal;
/* - verlaag x */
/* - c[x] = getal */
/* - verhoog x */
Tegen mijn code:
if (! ...)
/* als aan voorwaarde voldaan is, spring naar else */
c[x] = e;
/* (zie hierboven) */
else
c[x] = getal;
/* (zie hierboven) */
x++;
/* verhoog x */
M.a.w., even snel in het meest voorkomende geval en een beetje sneller in
het weinig voorkomende geval. De variant met ?: genereert ongeveer (of
zelfs hele
dezelfde
> Dit kan natuurlijk ook:
> if (...)
> {
> x--;
> c[x++] = getal;
> }
> Maar het geeft veel accolades voor weinig code. Persoonlijk vind ik de
> --x++ vorm veel logischer.
Wacht gewoon met x op te hogen tot je de oude waarde niet meer nodig
hebt... lijkt mij het meest logische. En het is echt niet trager; als je
me niet gelooft, moet je je compiler maar eens assembler laten genereren
van je code, dan kan je zien wat hij er juist mee aanvangt. 't Is niet
omdat je code minder C statements bevat, dat die ook minder assembler
instructies nodig heeft.
Om de zaken te illustreren, drie code fragmentjes en bijhorende
assembler zoals generereerd door gcc 2.96 onder linux op x86:
(1) de geldige versie van jouw laatste voorstel
***** begin C ************************************************
int f1(int *c, int x, int b, int e, int getal)
{
c[x++] = e;
if (b)
{
x--;
c[x++] = getal;
}
return x;
}
***** end C **************************************************
***** begin assembler ****************************************
f1:
pushl %ebp
movl %esp, %ebp
pushl %ebx
movl 12(%ebp), %ecx
movl 8(%ebp), %ebx
movl 16(%ebp), %edx
movl 20(%ebp), %eax
movl %eax, (%ebx,%ecx,4)
incl %ecx
testl %edx, %edx
je .L33
decl %ecx
movl 24(%ebp), %eax
movl %eax, (%ebx,%ecx,4)
incl %ecx
.L33:
movl %ecx, %eax
popl %ebx
popl %ebp
ret
***** end assembler ******************************************
(2) Mijn voorstel met if
***** begin C ************************************************
int f2(int *c, int x, int b, int e, int getal)
{
if (!b)
c[x] = e;
else
c[x] = getal;
x++;
return x;
}
***** end C **************************************************
***** begin assembler ****************************************
f2:
pushl %ebp
movl %esp, %ebp
movl 16(%ebp), %eax
movl 8(%ebp), %ecx
movl 12(%ebp), %edx
testl %eax, %eax
jne .L35
movl 20(%ebp), %eax
jmp .L37
.p2align 4,,7
.L35:
movl 24(%ebp), %eax
.L37:
movl %eax, (%ecx,%edx,4)
incl %edx
popl %ebp
movl %edx, %eax
ret
***** end assembler ******************************************
(3) Mijn voorstel met ?:
***** begin C ************************************************
int f3(int *c, int x, int b, int e, int getal)
{
c[x++] = !b ? e : getal;
return x;
}
***** end C **************************************************
***** begin assembler ****************************************
f3:
pushl %ebp
movl %esp, %ebp
pushl %ebx
movl 20(%ebp), %eax
movl 12(%ebp), %edx
movl %eax, %ecx
movl 16(%ebp), %eax
movl %edx, %ebx
incl %edx
testl %eax, %eax
je .L40
movl 24(%ebp), %ecx
.L40:
movl 8(%ebp), %eax
movl %ecx, (%eax,%ebx,4)
movl %edx, %eax
popl %ebx
popl %ebp
ret
***** end assembler ******************************************
--
Roel Schroeven
x3jmyi0yrrn3h001@sneakemail.com (anti-spam email address from sneakemail.com)
"Don't blame me if there are bugs. Blame the cute, furry one." - Rusty Russell
Technical Details
Message-ID:
<pan.2001.11.10.14.25.21.679.1818@sneakemail.com>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!supernews.com!newsfeed.direct.ca!look.ca!btnet-peer0!btnet-peer1!btnet!newsfeeds.belnet.be!news.belnet.be!ossa.telenet-ops.be!afrodite.telenet-ops.be.POSTED!not-for-mailReferences:
<3beb3ad1.46039351@news.pandora.be>Show Full Headers
Complete Article Headers
X-Google-Language: DUTCH,ASCII-7-bit X-Google-Thread: fcea4,d5a3535abd40b2f0 X-Google-Attributes: gidfcea4,public X-Google-ArrivalTime: 2001-11-10 05:26:23 PST Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!supernews.com!newsfeed.direct.ca!look.ca!btnet-peer0!btnet-peer1!btnet!newsfeeds.belnet.be!news.belnet.be!ossa.telenet-ops.be!afrodite.telenet-ops.be.POSTED!not-for-mail From: "Roel Schroeven" <x3jmyi0yrrn3h001@sneakemail.com> Subject: Re: C decrement / increment Newsgroups: be.comp.programming Message-ID: <pan.2001.11.10.14.25.21.679.1818@sneakemail.com> References: <3beb3ad1.46039351@news.pandora.be> User-Agent: Pan/0.10.0 (Unix) Mime-Version: 1.0 Content-Type: text/plain; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: 8bit X-Comment-To: "[EdGe]" <olx09654@online.be> Lines: 210 Date: Sat, 10 Nov 2001 13:25:23 GMT NNTP-Posting-Host: 213.224.75.149 X-Complaints-To: abuse@pandora.be X-Trace: afrodite.telenet-ops.be 1005398723 213.224.75.149 (Sat, 10 Nov 2001 14:25:23 MET) NNTP-Posting-Date: Sat, 10 Nov 2001 14:25:23 MET Organization: Telenet Internet