May 29, 2002
"Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:acu1lt$26dh$1@digitaldaemon.com...
>
<SNIP>
>
> In fact my usual loop construct is a count-down for loop like so:
>
> for (int i = container.size(); --i>=0; )
>   f(container[i]);
>
> Notice that container.size() only gets executed once, even if the compiler is stupid or you're in a debug build.
>
> Sean
>

>

I was discussing this with a friend lately and we both
came to the conclusion that looping backwards is safer
and easier (no need for a temporary count variable to
force optimization) in the general case. You can remove
elements from the container and it wouldn't matter.

Is there a reason you never see this kind of loop used
in examples in books? Is there a performance loss from
looping backwards?


--
Stijn
OddesE_XYZ@hotmail.com
http://OddesE.cjb.net
_________________________________________________
Remove _XYZ from my address when replying by mail



May 30, 2002
OddesE wrote:

> Is there a reason you never see this kind of loop used
> in examples in books? Is there a performance loss from
> looping backwards?

I do not know why this is not used in books,  but it is probably because when teaching how to use a for loop construct this would add an extra layer of complexity.

As for performance loss,  on the x86 processor this is not true - and in some cases performance may actually be improved due to optimising away the compare.

C 2002/5/30
May 30, 2002
"OddesE" <OddesE_XYZ@hotmail.com> wrote in message news:ad3d84$1eic$1@digitaldaemon.com...
> "Martin M. Pedersen" <mmp@www.moeller-pedersen.dk> wrote in message news:acthvu$5b9$1@digitaldaemon.com...
> > "Pavel Minayev" <evilone@omen.ru> wrote in message news:actg00$3eo$1@digitaldaemon.com...
> >
> > >     if (a == b)
> > >         c = f(z);
> > >     else
> > >         c = f(z + 1);
> > >
> > > No brackets! =)
> >
> > c = f(z+(a==b));
> >
> > No if! :-)
> >
> >
>
>
>
> You don't write an if, but the
> conditional check is there allright.
> Also, you are making your code dependant
> on the fact that false==0 and true==1.
> A dangerous assumption...
> I think this code is less clear at no gain.
> Losing the braces is allright, but losing
> the if! No!  :)

Then
c = f(z+(a==b)?1:0);

But, using Martin's method could be more optinal because I doen't require a branch, which is a slow down on modern CPU's that use read-ahead (because I has to stop the pipeline and reload stuff from the cashe or even the very slow RAM). Although I consider c = f(z+(a==b)) quite a neat one liner. But I agree that things of this nature begin to get criptic for the average programmer and I only use them when performace matters in the optimisation programming cycle.

> --
> Stijn
> OddesE_XYZ@hotmail.com
> http://OddesE.cjb.net
> _________________________________________________
> Remove _XYZ from my address when replying by mail
>
>
>
>


May 30, 2002
"OddesE" <OddesE_XYZ@hotmail.com> wrote in message news:ad3dn1$1f4v$1@digitaldaemon.com...
> "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:acu1lt$26dh$1@digitaldaemon.com...
> >
> <SNIP>
> >
> > In fact my usual loop construct is a count-down for loop like so:
> >
> > for (int i = container.size(); --i>=0; )
> >   f(container[i]);

> I was discussing this with a friend lately and we both
> came to the conclusion that looping backwards is safer
> and easier (no need for a temporary count variable to
> force optimization) in the general case. You can remove
> elements from the container and it wouldn't matter.

<SNIP>

I never though of that, interesting.

>
> --
> Stijn
> OddesE_XYZ@hotmail.com
> http://OddesE.cjb.net
> _________________________________________________
> Remove _XYZ from my address when replying by mail
>
>
>


May 30, 2002
Hi,

"OddesE" <OddesE_XYZ@hotmail.com> wrote in message news:ad3d84$1eic$1@digitaldaemon.com...
> > c = f(z+(a==b));
> > No if! :-)

> Losing the braces is allright, but losing
> the if! No!  :)

I agree. It was partly ment as a joke, and partly to illustrate that code isn't better, just because it is shorter. Same goes for braces. Regarding performance, I don't think that the code above is any better than code using ?: or if/else - given the right compiler.

Regards,
Martin M. Pedersen



May 30, 2002
"Martin M. Pedersen" <mmp@www.moeller-pedersen.dk> wrote in message news:ad5jg6$1sgk$1@digitaldaemon.com...
> Hi,
>
> "OddesE" <OddesE_XYZ@hotmail.com> wrote in message news:ad3d84$1eic$1@digitaldaemon.com...
> > > c = f(z+(a==b));
> > > No if! :-)
>
> > Losing the braces is allright, but losing
> > the if! No!  :)
>
> I agree. It was partly ment as a joke, and partly to illustrate that code isn't better, just because it is shorter. Same goes for braces. Regarding performance, I don't think that the code above is any better than code
using
> ?: or if/else - given the right compiler.
>
> Regards,
> Martin M. Pedersen
>
>


Hah, you fooled me  :P
Sorry if I reacted to hard... :)


--
Stijn
OddesE_XYZ@hotmail.com
http://OddesE.cjb.net
_________________________________________________
Remove _XYZ from my address when replying by mail




May 30, 2002
The only drawback to this type of loop that I know of is that the count variable *must* be signed or iterating all the way to zero doesn't work.

Oh, and it iterates backwards.  Sometimes the algorithm depends on going forward.

Sean

"OddesE" <OddesE_XYZ@hotmail.com> wrote in message news:ad3dn1$1f4v$1@digitaldaemon.com...
> "Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:acu1lt$26dh$1@digitaldaemon.com...
> >
> > In fact my usual loop construct is a count-down for loop like so:
> >
> > for (int i = container.size(); --i>=0; )
> >   f(container[i]);
> >
> > Notice that container.size() only gets executed once, even if the
compiler
> > is stupid or you're in a debug build.
>
> I was discussing this with a friend lately and we both
> came to the conclusion that looping backwards is safer
> and easier (no need for a temporary count variable to
> force optimization) in the general case. You can remove
> elements from the container and it wouldn't matter.
>
> Is there a reason you never see this kind of loop used
> in examples in books? Is there a performance loss from
> looping backwards?



May 30, 2002

anderson a écrit :

> "OddesE" <OddesE_XYZ@hotmail.com> wrote in message news:ad3d84$1eic$1@digitaldaemon.com...
> > "Martin M. Pedersen" <mmp@www.moeller-pedersen.dk> wrote in message news:acthvu$5b9$1@digitaldaemon.com...
> > > "Pavel Minayev" <evilone@omen.ru> wrote in message news:actg00$3eo$1@digitaldaemon.com...
> > >
> > > >     if (a == b)
> > > >         c = f(z);
> > > >     else
> > > >         c = f(z + 1);
> > > >
> > > > No brackets! =)
> > >
> > > c = f(z+(a==b));
> > >
> > > No if! :-)
> > >
> > >
> >
> >
> >
> > You don't write an if, but the
> > conditional check is there allright.
> > Also, you are making your code dependant
> > on the fact that false==0 and true==1.
> > A dangerous assumption...
> > I think this code is less clear at no gain.
> > Losing the braces is allright, but losing
> > the if! No!  :)
>
> Then
> c = f(z+(a==b)?1:0);
>
> But, using Martin's method could be more optinal because I doen't require a branch, which is a slow down on modern CPU's that use read-ahead (because I has to stop the pipeline and reload stuff from the cashe or even the very slow RAM).

The _perfect_ optimizer, may compile same code.
it must unassemble something like:

    mov  eax,a
    cmp  eax,b
    setz  al
    movzx  eax,al
    add  eax,z
    .
    .
witch i'm quite sure is much faster than

    mov  eax,a
    cmp  eax,b
    mov  eax,z
    jnz    not_equal    ;<-- arg .. poor microprocessor
    inc    eax
not_equal:
    .
    .
.. because a jump is the worst thing you can do to you dear microprocessor.
I have to check this kind of code with DM C++ and make a suggestion of
optimisation
on C++ thread if necessary.
All form like if (a==b) z++;  or if (a<b) z++; (here use adc intruction) .. can
be optimized the same way.
But i should stop brainstorm alone here as i would be not surprised if its
already optimized in DM C++

> Although I consider c = f(z+(a==b)) quite a neat one liner.

I agree, if

    c = f(z+(a==b))

is less readeable than

    if (a==b)
    {
        c = f(z+1);
    }
    else
    {
        c = f(z);
    }

100 lines are _more_ readeable than  500 lines.

roland



May 30, 2002
Keep in mind that from Pentium II upwards, there are conditional move instructions:

    mov    eax, a
    cmp    eax, b
    cmovnz    eax, 0      ; *
    cmovz    eax, 1      ; *
    add    eax, z



> The _perfect_ optimizer, may compile same code.
> it must unassemble something like:
>
>     mov  eax,a
>     cmp  eax,b
>     setz  al
>     movzx  eax,al
>     add  eax,z
>     .
>     .
> witch i'm quite sure is much faster than
>
>     mov  eax,a
>     cmp  eax,b
>     mov  eax,z
>     jnz    not_equal    ;<-- arg .. poor microprocessor
>     inc    eax
> not_equal:
>     .



May 31, 2002

"Christian Schüler" a écrit :

> Keep in mind that from Pentium II upwards, there are conditional move instructions:
>
>     mov    eax, a
>     cmp    eax, b
>     cmovnz    eax, 0      ; *
>     cmovz    eax, 1      ; *
>     add    eax, z
>

Really !
May be i have to change my Intel book: 486 cpu, 1990 ....

roland