Loop optimization

J

Jordan Abel

Interesting, I thought the two did produce different code, isn't this
true:

prefix op {
x = x + 1;
return x;
}

postfix op {
int tmp = x;
x = x + 1;
return tmp;
}

What does 'void context' mean and does this change the above code?

it means there's nowhere to return to, so no need to return. both would
become x = x + 1;
 
F

Flash Gordon

carl said:
Interesting, I thought the two did produce different code,

They do when you *use* the value.
> isn't this
true:

prefix op {
x = x + 1;
return x;
}

postfix op {
int tmp = x;
x = x + 1;
return tmp;
}

About right, although there are some subtleties, like there being no
guarantee when the increment occurs.
What does 'void context' mean and does this change the above code?

That means that you are not using the value.

int main(void)
{
int y;
int x=0;
y = x++; /* using the value, so it matters */
y = ++x; /* using the value, so it matters */
x++; /* not using the value, so how can you tell which occurred? */
++x; /* How can you tell if this did the same as the above or not? */
}

The subtlety I mentioned is that the increment can actually happen at
any time before the next sequence point, so things line ++i + ++i are
undefined, i.e. anything can happen. Check the comp.lang.c FAQ for details.
I'm new to this and would like to know whether I just wasted loads of
time changing my postfix to prefix in a futile attempt at optimisation!

1st rule of optimisation: don't do it.

You are not ready for the other rules yet, so just obey the first one
and right code that works.
 
K

Keith Thompson

carl said:
Interesting, I thought the two did produce different code, isn't this
true:

prefix op {
x = x + 1;
return x;
}

postfix op {
int tmp = x;
x = x + 1;
return tmp;
}

What does 'void context' mean and does this change the above code?

I'm new to this and would like to know whether I just wasted loads of
time changing my postfix to prefix in a futile attempt at optimisation!

A "void context" is a context in which an expression is evaluated only
for its side effects, with the actual result of the expression being
ignored.

"i++" yields the (previous) value of i; as a side effect, i is incremented.

"++i" yields the value of i+1; as a side effect, i is incremented.

If the result is used as part of a larger expression, such as
x = i++;
the compiler may need to use a temporary to hold the previous value of
i -- but since "x = i++;" and "x = ++i;" aren't semantically
equivalent, there's not much point in comparing their performance.

If the result is discarded, as in a statement context:
i++;
++i;
the expression *theoretically* yields the same result as it would in
any other context, but any decent compiler will be smart enough to
take advantage of the fact that the result isn't used. If a compiler
generated significantly different code for "i++;" and "++i;", it's
probably a bug.

Note that the first and third expression in a "for" statement also
provide a void context, so
for (i = 0; i < 10; i++) { ... }
and
for (i = 0; i < 10; ++i) { ... }
are equivalent -- and many programmers won't even notice the
difference when reading the code.
 
C

Christian Bau

"haroon said:
Hi,
I have two versions of a loop. I want to know which one is more
efficient. and is there any way to make it even more efficient?

1- for (i = 0; str[i++] != '\0';) ;

2- for (i = 0; str[] != '\0'; ++i) ;

Call strlen () instead.
 
C

Christian Bau

Flash Gordon said:
1) You response belongs *under* the text you are replying to, not above.
2) Have you proved his by measuring the performance of the code
generated by *all* compilers?
3) It is easy for a compiler to translate from the array version to the
pointer version and so the pointer version is unlikely to produce a
faster executable.
4) Many compilers will produce the same code whether you use pointer
arithmetic or arrays.

5) Many compilers will produce faster code for arrays :)

Seriously, on many C implementations calculating the address of an array
element comes for free (on PowerPC and x86 implementations), and the
array + index version has only one variable (i) that needs to be updated
instead of two (pointer and i).

Apart from that, a good strlen () implementation could beat the loop by
a considerable factor.
 
C

Christian Bau

"carl said:
Interesting, I thought the two did produce different code, isn't this
true:

prefix op {
x = x + 1;
return x;
}

postfix op {
int tmp = x;
x = x + 1;
return tmp;
}

What does 'void context' mean and does this change the above code?

It means the situation where you throw away the result. Implicit:

i++;
++i;

or explicit:

(void) i++;
(void) ++i;

The first one means: "Take i, increase it by one, take the original
value, throw it away". The second one means "Take i, increase it by one,
take the new value, throw it away". Any decent compiler will not produce
any code for "take the original value, throw it away" or "take the new
value, throw it away", so the only thing that remains is "take i,
increase it by one" in both cases.
 

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
474,173
Messages
2,570,938
Members
47,475
Latest member
NovellaSce

Latest Threads

Top