🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: be.comp.programming
Article #12527

Re: C decrement / increment

#12527
From: Roel Schroeven
Date: Sat, 10 Nov 2001 13:25
210 lines
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-mail
References: <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