++x is more optimised than x++ ???

  • Thread starter karthikbalaguru
  • Start date
K

karthikbalaguru

I came across a nice example and info that claim that ++x is optimised
than x++.
Is it so ?

For example.
for(x = 0; x < 10; x++)
There is a simple fix for this, and it will optimize your loop, ever
so slightly.
for(x = 0; x < 10; ++x)
It can save milliseconds on your code rotations, for those using for
loops like this, this is a much faster way to parse through your
data.

Is it so ? How is it possible that ++x is faster than x++ ?

Thx in advans,
Karthik Balaguru
 
J

jacob navia

karthikbalaguru said:
I came across a nice example and info that claim that ++x is optimised
than x++.
Is it so ?

For example.
for(x = 0; x < 10; x++)
There is a simple fix for this, and it will optimize your loop, ever
so slightly.
for(x = 0; x < 10; ++x)
It can save milliseconds on your code rotations, for those using for
loops like this, this is a much faster way to parse through your
data.

Is it so ? How is it possible that ++x is faster than x++ ?

Thx in advans,
Karthik Balaguru

In theory, ++c just increments c. c++ increments c and returns
the OLD value, so the old value must be saved.

In practice there isn't any difference for most compilers. If
the old value is discarded, they throw the saving of the
old value away and generate the same code as for ++c.
 
S

Stephen Sprunk

karthikbalaguru said:
I came across a nice example and info that claim that ++x is
optimised than x++. Is it so ?

For example.
for(x = 0; x < 10; x++)
There is a simple fix for this, and it will optimize your loop, ever
so slightly.
for(x = 0; x < 10; ++x)
It can save milliseconds on your code rotations, for those using for
loops like this, this is a much faster way to parse through your
data.

Is it so ? How is it possible that ++x is faster than x++ ?

Decades ago, when compilers were pretty bad at optimizing, that was likely
true. Nowadays, they should compile to identical instructions except in
cases where the resulting value of the expression matters. For instance, "y
= ++x;" is likely to still be faster than "y = x++;", but the two statements
don't do the same thing.

S
 
T

Tim Prince

jacob said:
In theory, ++c just increments c. c++ increments c and returns
the OLD value, so the old value must be saved.

In practice there isn't any difference for most compilers. If
the old value is discarded, they throw the saving of the
old value away and generate the same code as for ++c.
It would require a different example, to show an advantage for ++x on
CPUs which support it better in the instruction set, like old PPC Macs.
 
K

Kelsey Bjarnason

I came across a nice example and info that claim that ++x is optimised
than x++.
Is it so ?

For example.
for(x = 0; x < 10; x++)
There is a simple fix for this, and it will optimize your loop, ever
so slightly.
for(x = 0; x < 10; ++x)
It can save milliseconds on your code rotations, for those using for
loops like this, this is a much faster way to parse through your
data.

Is it so ? How is it possible that ++x is faster than x++ ?

The reasoning probably goes something like this:

var = ++x stores the incremented value of x in var
var = x++ stores the unincremented value of x in var
some compilers may generate a temporary for this:
temp = x
x++
var = temp
thus you should use ++x instead of x++

The main problem with this is that any compiler worth its salt won't
bother unless the unincremented value is actually needed; in the loop,
it's not. The value of x++ isn't used at all, no need to store the value,
so why bother with the overhead?

A quick test with gcc shows it generating identical code in both cases;
I'd expect the same from pretty much any compiler these days.
 
U

user923005

I came across a nice example and info that claim that ++x is optimised
than x++.
Is it so ?

For example.
for(x = 0; x < 10; x++)
There is a simple fix for this, and it will optimize your loop, ever
so slightly.
for(x = 0; x < 10; ++x)
It can save milliseconds on your code rotations, for those using for
loops like this, this is a much faster way to parse through your
data.

Is it so ? How is it possible that ++x is faster than x++ ?

It isn't. Or it could be. It could also be slower. The C language
does not specify the speed of things.

Tell me where you see the big improvement in the generated assembly
language here:

C:\tmp>type foo.c
#include <stdio.h>
#include <stdlib.h>

int
main (void)
{
int i;
i = rand();
i++;
printf("%d",i);
i = rand();
++i;
printf("%d",i);

return 0;
}

C:\tmp>type foo.asm
; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\tmp\foo.c
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

_DATA SEGMENT
$SG3568 DB '%d', 00H
ORG $+1
$SG3569 DB '%d', 00H
_DATA ENDS
PUBLIC _main
EXTRN _printf:pROC
EXTRN _rand:pROC
; Function compile flags: /Ogtpy
; File c:\tmp\foo.c
_TEXT SEGMENT
_main PROC

; 7 : int i;
; 8 : i = rand();

call _rand

; 9 : i++;

add eax, 1

; 10 : printf("%d",i);

push eax
push OFFSET $SG3568
call _printf

; 11 : i = rand();

call _rand

; 12 : ++i;

add eax, 1

; 13 : printf("%d",i);

push eax
push OFFSET $SG3569
call _printf
add esp, 16 ; 00000010H

; 14 :
; 15 : return 0;

xor eax, eax

; 16 : }

ret 0
_main ENDP
_TEXT ENDS
END

dcorbit@DCORBIT64 /c/tmp
$ gcc -O3 -W -Wall -ansi -pedantic -S foo.c

dcorbit@DCORBIT64 /c/tmp
$ cat foo.c
#include <stdio.h>
#include <stdlib.h>

int
main (void)
{
int i;
i = rand();
i++;
printf("%d",i);
i = rand();
++i;
printf("%d",i);

return 0;
}

dcorbit@DCORBIT64 /c/tmp
$ cat foo.s
.file "foo.c"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "%d\0"
.text
.p2align 4,,15
..globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl $16, %eax
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
call __alloca
call ___main
call _rand
movl $LC0, (%esp)
incl %eax
movl %eax, 4(%esp)
call _printf
call _rand
movl $LC0, (%esp)
incl %eax
movl %eax, 4(%esp)
call _printf
xorl %eax, %eax
leave
ret
.def _rand; .scl 3; .type 32; .endef
.def _printf; .scl 3; .type 32; .endef
 
M

Marjancek

I came across a nice example and info that claim that ++x is optimised
than x++.
Is it so ?

For example.
for(x = 0; x < 10; x++)
There is a simple fix for this, and it will optimize your loop, ever
so slightly.
for(x = 0; x < 10; ++x)
It can save milliseconds on your code rotations, for those using for
loops like this, this is a much faster way to parse through your
data.

Is it so ? How is it possible that ++x is faster than x++ ?

Thx in advans,
Karthik Balaguru

Perhaps your post would have more sense in lang.c++, as there there IS
a diference, regardless of the compiler, due to operator overloadings.

Mariano
 
G

Gordon Burditt

I came across a nice example and info that claim that ++x is optimised
than x++.

If the value of the expression is not used, the generated code for
++x may be more the same as the code for x++ than the generated
code for x++ is the same as the code for ++x. (Note: Standard C
does not define the "is more equal" operator.) Reasonable compilers
will generate identical code in this case. Identical code is *NOT*
guaranteed to execute at identical speed (consider pipelining, and
cache contents of previous code, task switches, interrupts, etc).
Is it so ?

Any statement of the form "A is faster than B, A is slower than B,
or A is about the same speed as B" is false (even if B is "Repeat
A one million times"), unless the conditions of test such as CPU,
compiler version AND checksum, and compile-time options are specified.
For example.
for(x = 0; x < 10; x++)
There is a simple fix for this, and it will optimize your loop, ever
so slightly.

There is no guarantee of that. Reasonable compilers will generate
identical code in both cases.
for(x = 0; x < 10; ++x)
It can save milliseconds on your code rotations, for those using for
loops like this, this is a much faster way to parse through your
data.

Or it could COST kiloseconds.
Is it so ? How is it possible that ++x is faster than x++ ?

Standard C does not guarantee anything about performance.
 
P

Peter Nilsson

Note that the answer in C++ is different because x may be
a class with overloaded increment operators.

It's not a _fix_, it's a micro-optimisation.

It may make it faster, it may make it slower. But if the
change will only save 20 seconds cpu time over the 10 years
the program may typically be employed, then it's not even
worth spending 2 minutes profiling!
It would require a different example, to show an advantage for
++x on CPUs which support it better in the instruction set,
like old PPC Macs.

The difference is usually much clearer with pointer increments...

while (*s++ = *t++) /* mac 68k */
;

verses

if (*s = *t) /* pentium & ppc */
while (*++s = *++t)
;

You will find cases where compiler optimisation isn't perfect
at things like...

while (i-- < 10)
...stuff...

....but it's usually a compiler issue, not an instruction set
issue.
 
A

Ark Khasin

Peter said:
The difference is usually much clearer with pointer increments...

while (*s++ = *t++) /* mac 68k */
;

verses

if (*s = *t) /* pentium & ppc */
while (*++s = *++t)
;

You will find cases where compiler optimisation isn't perfect
at things like...

while (i-- < 10)
...stuff...

...but it's usually a compiler issue, not an instruction set
issue.
It often /is/ an instruction set issue.
If memory serves me right, e.g. in ARM in Thumb mode pointers are
optimized for post-increment and pre-decrement.
It's a different story that a good compiler would virtually rewrite your
snippet of code in an equivalent and faster-for-this-machine way.
To do so, it needs to recognize your snippet as transformable: it's the
best reason to write the code in cliches (common idioms) and avoid
clever constructs and blocks nested CHAR_BIT deep :)
-- Ark
 
D

Dave Dunfield

I came across a nice example and info that claim that ++x is optimised
If all you are relying on is the side effect (ie: incrementing and not using
the resultant value within the same expression), there should be no
difference at all for any decent remotely modern compiler. In cases
where you are using the resulting value, the code generated may be
different, but in almost all cases should be equally efficient - of course
the two constructs mean two different things in terms of the resultant
value, so you cannot directly compare them anyway.


Historically, there is a small basis of truth in this for certain accumulator
bound operations in very early compilers. This comes from the fact that
++x evaluates to the new (incremented) value of x, while x++ evaluates
to the old (pre-increment) value of x. This means that when the value of
an x++ expression is used, the "old" value of x may have to be preserved
under some architectures.

Modern compilers are bright enough to take advantage of architectural
features which accomodate this, and can rearrange code, defer the
increment etc. to almost always produce equivalent code for either
construct (in fact with some architectures x++ can be evaluated more
efficiently than ++x in certain cases).

Some early compilers were more literal, generating code with each
reduction, and might generate extra code to recover the lost previous
value (ie: decrement after the increment/store) - a particularly brain-
dead compiler might have done this even if the result of the expression
was not required to be preserved (I confess - mine did this in very early
versions) - which ment that ++x was in fact more efficient than x++.

But - as noted above, only with primitive compilers for certain
architectures - If you are using modern tools, write the code which
best describes the operations you need to perform, and trust the
compiler to do it's job. Attempts to optimize at this source code
level rarely provide tangible benefits, and your time will be much
better spent on algorithmic optimizations (assmuming you are
have reason to spend time optimizing).

Dave
 
M

Martin Wells

Kathik:
Is it so ? How is it possible that ++x is faster than x++ ?


As regards C++, either could be more efficient depending upon the
user's definition of the overloaded operator function. And, in
general, the user's prefix version tends to be faster than the postfix
version because the postfix version tends to involve creating a copy.

But we're talking about C here.

The purpose of x++ is to take the value, then increment it. (Quite
easily understood when reading from left to right).

The purpose of ++x is to increment it, then take the value. (Quite
easily understood when reading from left to right).

Now ask yourself, why should opening a door and then closing a window
be any faster than closing a window and then opening a door? (No smart-
allec answers thank you very much, such as that it depends whether
you're downstairs and the window is upstairs).

In the following code:

Func(x++);

, why should there be any kind of copy? Why wouldn't it simply be
treated as "take the value, then increment"? i.e.:

Func(x); ++x;

Anyway, to answer your question, if any compiler even makes a
difference between the two expressions (assuming the value of the
expression is discarded), then I'd probably get myself a different
compiler.

Martin
 
P

pete

Martin said:
Kathik:


As regards C++, either could be more efficient depending upon the
user's definition of the overloaded operator function. And, in
general, the user's prefix version tends to be faster than the postfix
version because the postfix version tends to involve creating a copy.

But we're talking about C here.

The purpose of x++ is to take the value, then increment it. (Quite
easily understood when reading from left to right).

The purpose of ++x is to increment it, then take the value. (Quite
easily understood when reading from left to right).

Now ask yourself, why should opening a door and then closing a window
be any faster than closing a window and then opening a door?
(No smart-allec answers thank you very much,
such as that it depends whether
you're downstairs and the window is upstairs).

In the following code:

Func(x++);

, why should there be any kind of copy? Why wouldn't it simply be
treated as "take the value, then increment"? i.e.:

Func(x); ++x;

That doesn't mean the same thing.
There's a sequence point between argument evaluation
and the actual function call.

(++x, Func(x - 1)) means the same thing as Func(x++).



/* BEGIN new.c output */

10
00
10

/* END new.c output */


/* BEGIN new.c */

#include <stdio.h>

void Func(int y);

int x;

int main(void)
{
puts("/* BEGIN new.c output */\n");

x = 0;
Func(x++);

x = 0;
Func(x); ++x;

x = 0;
(++x, Func(x - 1));

puts("\n/* END new.c output */");
return 0;
}

void Func(int y)
{
printf("%d%d\n", x, y);
}

/* END new.c */
 
M

Martin Wells

pete:
That doesn't mean the same thing.
There's a sequence point between argument evaluation
and the actual function call.


I over-simplified the example for sake of the discussion.

Martin
 
R

Richard

Martin Wells said:
pete:



I over-simplified the example for sake of the discussion.

Martin

This is not, as you have discovered, the place to do that. Although in
this case I think it was worth highlighting the difference as it would
be very instructive for a newbie learning C and convincingly
demonstrates sequencing in a simple, straightforward manner.
 
A

Army1987

In the following code:

Func(x++);

, why should there be any kind of copy? Why wouldn't it simply be
treated as "take the value, then increment"? i.e.:

Func(x); ++x;

What if Func somehow knows x's address? There is a sequence point
after the arguments are evaluated and before the function is
called, so it should see the incremented value.

Maybe ++x, Func(x - 1); would do it.
 
P

pete

Richard said:
This is not, as you have discovered, the place to do that. Although in
this case I think it was worth highlighting the difference as it would
be very instructive for a newbie learning C and convincingly
demonstrates sequencing in a simple, straightforward manner.

And I want to restate that
(++x, Func(x - 1)) means the same thing as Func(x++)
and also say:
that the two expressions mean the same thing
regardless of the return type of Func and
regardless of whether or not x is an expression of type int
with an initial value of INT_MAX.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,481
Members
44,900
Latest member
Nell636132

Latest Threads

Top