You are correct as long as the increment is a lone statement, instead of being used in a longer statement.
x++ and ++x are different.
This is a quote from (Schildt, H. (2002), "C: The Complete Reference, Fourth Edition", "The Increment and Decrement Operators", Osborne/McGraw-Hill)
So to answer your question based on this, do you want your indexing to be incremented before or after your code runs the line?"... When an increment or decrement operator precedes its operand, the increment or decrement operation is performed before obtaining the value of the operand for the use in the expression. If the operator follows its operand, the value of the operand is obtained before incrementing or decrementing it. For instance,
sets y to 11. However, if you write the code asCode:x = 10; y = ++x;
y is set to 10."Code:x = 10; y = x++;
Oh, I missed the word "first". My bad. Guess this is a danger when the code context provided is longer than necessary and contains a scenario where the difference does matter.Originally Posted by christop
Eh, be careful with Herbert Schildt books. They are notorious for being easy to read but technically deficient.Originally Posted by Click_here
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
there may be changes or may not but efficinece varies,preincrement works efficiently..here is an example..
Code:int main() { int i, j ,k; #if 0 for (i = 0; i < 10000; i++) for (j = 0; j < 10000; j++) for (k = 0; k < 40; k++); #else for (i = 0; i < 10000; ++i) for (j = 0; j < 10000; ++j) for (k = 0; k < 40; ++k); #endif }
I compiled the above code with 0 and 1 for the #if macro and found that the resultant binaries were bitwise same. So, the preVspost changes contributed nothing for performance as the resultant binaries were exactly identical in either case. So, it's irrelevant if you use post or pre increment for the "for" loop index variable.
I realized that it does not matter if the operation is pre or post increment or assignment, if the value of the expression is not stored at all. So I modified the code to store the return value of the pre/post increment operations and decided to measure the performance. So the code became:
Code:int main() { int i, j ,k, t; #if 1 for (i = 0; i < 10000; t = i++) for (j = 0; j < 10000; t = j++) for (k = 0; k < 40; t = k++); #else for (i = 0; i < 10000; t = ++i) for (j = 0; j < 10000; t = ++j) for (k = 0; k < 40; t = ++k); #endif }
This time I strongly believed that there will be a difference in performance and compiled with the values of 0 and 1 for the #if macro. I did a test run of about 10 iterations for each of post and pre increments. The result was however surprising. Post-increment consistently outperformed pre-increment and finished faster always. I was startled about this observation.
Since so many performance centric people have used pre-increment instead of post-increment in the past, I believed there must be some reason for people using pre-increment. I asked this in a SUSE mailing list for an explanation of the above observation. There are people in SUSE who are as long-experienced with computers as my age. They provided me the answer for this. Earlier, gcc used to generate sub-optimal code for post-increment and that is why pre-increment was used then. Compilers have come a long way and programmers don't need to think in weird way to outsmart the compilers anymore.
That is weird!Post-increment consistently outperformed pre-increment and finished faster always
I tried to play around with that in code:blocks, but I couldn't reproduce your results
Code:void delay_some_time(void) { int i; for(i=0;i<0x100;++i); return; } 00401A95 push %ebp 00401A96 mov %esp,%ebp 00401A98 sub $0x10,%esp 00401A9B movl $0x0,-0x4(%ebp) 00401AA2 jmp 0x401aa7 <delay_some_time+18> 00401AA4 incl -0x4(%ebp) 00401AA7 cmpl $0xff,-0x4(%ebp) 00401AAE jle 0x401aa4 <delay_some_time+15> 00401AB0 leave 00401AB1 retCode:void delay_some_time(void) { int i; for(i=0;i<0x100;i++); return; } 00401A95 push %ebp 00401A96 mov %esp,%ebp 00401A98 sub $0x10,%esp 00401A9B movl $0x0,-0x4(%ebp) 00401AA2 jmp 0x401aa7 <delay_some_time+18> 00401AA4 incl -0x4(%ebp) 00401AA7 cmpl $0xff,-0x4(%ebp) 00401AAE jle 0x401aa4 <delay_some_time+15> 00401AB0 leave 00401AB1 ret
The reason you might not be able to reproduce it is because you are not using an ancient compiler for the desktop. Notice how maheshmahi takes back all of the performance optimization with his closing remarks. You don't need to outsmart the compiler like this anymore. This rightfully belongs nowhere on your list of possible optimizations for C programs, I think.
In C++ the optimization is somewhat more important because of classes and copy semantics, but I seriously doubt that as a useful one. If you followed an iterator approach, your custom iterators would have to be very expensive to copy to impact performance. In my experience that is hard to achieve.
I'm not sure how one loop is going to run faster than the other when any reasonable compiler is going to remove those loops as dead code anyway. I wonder if he was trying to test how fast the code was with optimizations turned off, which obviously will give misleading results.
You are correctRead his post more carefully. He said he only found a difference if he stores the result of the pre/post-increment.
He got the same result as you if he used stand-alone pre/post-increment.
Here is a comparison of the other code
As expected, it's inc and the mov, or mov and then inc.Code:void delay_some_time(void) { int i,t; for(i=0;i>=0xFF;t=i++); return; } 00401A95 push %ebp 00401A96 mov %esp,%ebp 00401A98 sub $0x10,%esp 00401A9B movl $0x0,-0x8(%ebp) 00401AA2 jmp 0x401aad <delay_some_time+24> 00401AA4 mov -0x8(%ebp),%eax 00401AA7 mov %eax,-0x4(%ebp) 00401AAA incl -0x8(%ebp) 00401AAD cmpl $0xfe,-0x8(%ebp) 00401AB4 jg 0x401aa4 <delay_some_time+15> 00401AB6 leave 00401AB7 ret void delay_some_time(void) { int i,t; for(i=0;i>=0xFF;t=++i); return; } 00401A95 push %ebp 00401A96 mov %esp,%ebp 00401A98 sub $0x10,%esp 00401A9B movl $0x0,-0x8(%ebp) 00401AA2 jmp 0x401aad <delay_some_time+24> 00401AA4 incl -0x8(%ebp) 00401AA7 mov -0x8(%ebp),%eax 00401AAA mov %eax,-0x4(%ebp) 00401AAD cmpl $0xfe,-0x8(%ebp) 00401AB4 jg 0x401aa4 <delay_some_time+15> 00401AB6 leave 00401AB7 ret
I'd love to see what the old compiler is doing if anyone has got one
Not always - If the subroutine was declared as volatile, the compiler won't remove it (that's what I had to do for this example).I'm not sure how one loop is going to run faster than the other when any reasonable compiler is going to remove those loops as dead code anyway.
That being said, I think that we are starting to drift off topic - I'll have to "googlate" some articles; see if I can learn more about this - Does anyone have any recommendations?
Your loop is wrong, and the assembly makes this error obvious:
It should be jl or jb, not jg.Code:00401AAD cmpl $0xfe,-0x8(%ebp) 00401AB4 jg 0x401aa4 <delay_some_time+15>
Sometimes the word "frustrated" doesn't cut it. I really need to check my code a lot closer than I do before posting it.
memcpy -> You are a master at what you do for picking that up so quickly.