I have few questions ...
Q1. Why does pre-increment of a variable work faster than post-increment? If the statement is true, then why do we do use post increment while writing the code most of the time?
Q2. C is a top-down approach whereas C++ is a bottom-up approach. Now what does it actually mean?
Thanks in advance. :)
Two questions :: pre-post increment & top-down/bottom-up approach
Started by $AP, Dec 28 2008 01:43 AM
11 replies to this topic
#1
Posted 28 December 2008 - 01:43 AM
|
|
|
#2
Posted 28 December 2008 - 02:02 AM
A1: The idea is a sense of programming...u can use pre-incremenet (for example in the loop ) and maybe the usage of post increment is most significant than the pre-increment ... u can say for ex : for(i=0;i<10;i++) similarly as for(i=0;i<11;++i)
A2:I dont know what u mean exactly...but this will be due to that C++ is update to C ...not all C++ programs can be written i C but the vice versa is true
A2:I dont know what u mean exactly...but this will be due to that C++ is update to C ...not all C++ programs can be written i C but the vice versa is true
#3
Posted 28 December 2008 - 03:07 AM
$AP said:
Q1. Why does pre-increment of a variable work faster than post-increment? If the statement is true, then why do we do use post increment while writing the code most of the time?
Consider this code:
int a = 0;
int b = i++;
/* what happens is something similar to :
int& operator++( int ) {
int current; // new copy is created
current = *this; // new copy is assigned
// increment this
return current;
}
*/
and :
int a = 0;
int b = ++i;
/* what happens is something similar to :
int& operator++( void ) {
// increment this
return *this;
}
*/
It should be pretty obivious :p
#4
Posted 28 December 2008 - 05:34 AM
2. You'll have to explain what you mean. I program the same way in both of them. They may encourage different styles of programming, but I'm not familiar with the terms "top down" and "bottom up" referring to a language, just a coding style.
#5
Posted 28 December 2008 - 01:54 PM
Quote
u can say for ex : for(i=0;i<10;i++) similarly as for(i=0;i<11;++i)
Wrong. In this case, post-inc and pre-inc makes no difference on the loop boundary. So you should write:
for(i=0;i<10;i++)
do_something();
Orfor(i=0; i<10; ++i) do_something();
For builtin type, pre-inc and post-inc will result in same binary code for the previous two ways. C programs use both ways interchangably and they indeed are equivalent. However:
1. They are different if the value of the pre-inc and post-inc expression is used.
j = ++i; is not equivalent to j=i++;
j=*p++ is not equivalent to j=*++p;
assuming they are all valid expression and mean what they appear to mean.
2. You are told pre-inc could be more efficient than post-inc for a good reason when you're working on non-builtin types, eg. iterators, eg, you should use
for(std::vector<int>::iterator i=vi.begin(); i!=vi.end(); ++i)
{
//...
}
Instead of,
for(std::vector<int>::iterator i=vi.begin(); i!=vi.end(); i++)
{
//...
}
because they are equivalent function-wise but the latter is slightly less efficient.
Why? I guess Julmuri has already told you (or he meant to tell you but his code has a small defect, a reference to a local variable should not be returned)
Let's examine a typical implementation for a post-increment operator:
const foo foo::operator++(int)
{
foo f(*this); // make a copy of the value before increment\
++foo; // call the pre-increment operator,
// implementation of which skipped.
return f; //
}
As we can tell from the above code, on top of the cost of pre-increment operator, calls to copy constructor are made 2 times. That is the difference people are talking about.
#6
Posted 30 December 2008 - 10:55 PM
$AP said:
I have few questions ...
Q1. Why does pre-increment of a variable work faster than post-increment? If the statement is true, then why do we do use post increment while writing the code most of the time?
Q2. C is a top-down approach whereas C++ is a bottom-up approach. Now what does it actually mean?
Thanks in advance. :)
Q1. Why does pre-increment of a variable work faster than post-increment? If the statement is true, then why do we do use post increment while writing the code most of the time?
Q2. C is a top-down approach whereas C++ is a bottom-up approach. Now what does it actually mean?
Thanks in advance. :)
First Question
Neither statement is technically faster. A pre-increment, such as ++i, will simply increment the variable before the whole of the line is computed, whereas a post-increment will increment the variable after the whole line is computed. For example:
// Assume a is 7 and b is 5, both integers. int post = a++ - b; // Here post would be 7 - 5 == 2, then a becomes 8.
// Assume a is 7 and b is 5, both integers. int pre = ++a - b; // Here pre would be 8 - 5 == 3, a became 8 first.
Second Question
Your statement is wrong, but I can explain what they are. ;)
Top-down programming means you start with high level material, and coding as if the low-level material (for example, some complex functions) have already been coded. Once done, you code the more complex material, repeating the process until you are done coding everything you have used. Bottom-up is the exact opposite approach; you code the complex functions and such first, then get higher and higher level until you get to your main implementation which should essentially use all the low-level code you have already pumped out. This is seen more frequently in object-oriented programming, and OOP is seen more frequently in C++ rather that C (no one likes to deal with structs when classes can be used and are more convenient). So your statement, although not correct, is generally true. You see bottom-up more often in C++ as opposed to C.
Hope this clears everything up, since the previous posts were somewhat unclear or just completely unhelpful (sam961's post was utterly useless and completely wrong).
#7
Posted 31 December 2008 - 01:23 AM
Steve.L said:
First Question
Neither statement is technically faster. A pre-increment, such as ++i, will simply increment the variable before the whole of the line is computed, whereas a post-increment will increment the variable after the whole line is computed.
Neither statement is technically faster. A pre-increment, such as ++i, will simply increment the variable before the whole of the line is computed, whereas a post-increment will increment the variable after the whole line is computed.
Try to run this code :p
int __cdecl main( int argc, char** argv ) {
std::vector<int> vec;
std::vector<int>::iterator vec_iter;
std::vector<int>::const_iterator vec_end;
clock_t time;
// push 10 000 000 items into our vector
for ( int i = 0; i < 10000000; ++i ) {
vec.push_back( i );
} // for
// save vector end to make looping faster :p
vec_end = vec.end();
time = std::clock();
for ( vec_iter = vec.begin(); vec_iter != vec_end; ++vec_iter ) {
// some operation here, we will just increment the value
++(*vec_iter);
} // for
time = std::clock() - time;
std::cout << "Pre increment time: "
<< time
<< std::endl;
time = std::clock();
for ( vec_iter = vec.begin(); vec_iter != vec_end; vec_iter++ ) {
// some operation here, we will just the increment value
++(*vec_iter);
} // for
time = std::clock() - time;
std::cout << "Post increment time: "
<< time
<< std::endl;
return 0;
} // main
Mine output:
Pre increment time: 2813 Post increment time: 17469
Like lance pointed out, it makes sense to use pre increment for non native types if you just need to increment it.
#8
Posted 31 December 2008 - 11:05 AM
Your test isn't completely valid. True, a pre-increment will run slightly faster than a post-increment in the general case, due to the fact that a temporary variable will be created in a post-increment to store the value before incrementing, however in a loop, the running time of incrementing a variable is insignificant compared to the running time of the body of the loop, and therefore both methods will yield the same running time. This has already been proven numerous times around the web, so I won't go into details. It can also be shown, in a similar test to yours (with optimization turned off), that post-increments will run more quickly than pre-increments. Funny, huh?
Don't try to prove running time by measuring, prove it in theory first. They will average out to be the same, however there are cases where pre is faster than post, and vice-versa. And in nearly every case, the difference is not enough that you will ever notice it.
Don't try to prove running time by measuring, prove it in theory first. They will average out to be the same, however there are cases where pre is faster than post, and vice-versa. And in nearly every case, the difference is not enough that you will ever notice it.
#9
Posted 31 December 2008 - 04:55 PM
Quote
It can also be shown, in a similar test to yours (with optimization turned off), that post-increments will run more quickly than pre-increments.
I'd love to see an example. Do not put an idle loop in the pre-incrementor though.
For non-builtin types, post-increment is theoretically slightly slower than its pre-increment counterpart, even though the difference may hardly be noticeable.
The same holds true that a virtual function call will be slightly slower than its non-virtual counterpart because of the one extra level of indirection. You'll hardly notice that too but I am not aware of any C++ programmers who will blindly define all member functions as virtual. If you choose to program in C/C++, you basically manifest that you care about these little bits. True, many C++ programmers advocate std::string in favor of c style string, but there's a tradeoff. While in pre/post-increment case, there is no reasonable situation in which a post-increment will be faster than a pre-increment. A C++ programmer should form a habit of using pre-increment in situations where both are functionally equivalent.
A difference between post-increment and pre-increment operators(for non-build in type) is generally more significant than that between virtual and non-virtual function; think about the case when the class allocates memory dynamically or acquires resources in its copy contrustors.
Here is another example, what's so signifcantly different between ++i and i+=1 or even i=i+1? Why don't the language designers eliminate this language feature and stick to the more general form to make the language simpler? Because in C/C++, every little bit counts! That some practice is not practically significantly less efficient than another is not a good argument to say they are equal.
IMHO, Julmri's test is both relevant and valid.
Edited by Lance, 31 December 2008 - 05:39 PM.
#10
Posted 31 December 2008 - 10:25 PM
I found this page on the topic, it's pretty interesting. Both loops are exactly the same, minus the obvious pre- and post-increment difference.
Anyways, there's no use arguing over it, I'm just pointing out that, in practice, it generally doesn't matter which method you use.
Anyways, there's no use arguing over it, I'm just pointing out that, in practice, it generally doesn't matter which method you use.
#11
Posted 01 January 2009 - 03:02 PM
I checked that post. Here is my result. They generate identical assembly code, which agrees with my belief that post increment and pre increment are identidcal for builtin types.
test1.cpp
test2.cpp
compile them with g++
And the generated assembly files are virtually identical(execpt the source file name). So it's been proven theoretically pre/post increment are identical. So I need to actually run it to know they are the same?
BTW, here is the assembly file
test1.cpp
void func()
{
}
int main()
{
int i;
for(i=0; i<0x1000; ++i)
func();
}
test2.cpp
void func()
{
}
int main()
{
int i;
for(i=0; i<0x1000; i++)
func();
}
compile them with g++
g++ -O2 -S test1.cpp test2.cpp
And the generated assembly files are virtually identical(execpt the source file name). So it's been proven theoretically pre/post increment are identical. So I need to actually run it to know they are the same?
BTW, here is the assembly file
.file "test1.cpp" .text .align 2 .p2align 4,,15 .globl _Z4funcv .type _Z4funcv, @function _Z4funcv: .LFB2: pushl %ebp .LCFI0: movl %esp, %ebp .LCFI1: popl %ebp ret .LFE2: .size _Z4funcv, .-_Z4funcv .globl __gxx_personality_v0 .align 2 .p2align 4,,15 .globl main .type main, @function main: .LFB3: leal 4(%esp), %ecx .LCFI2: andl $-16, %esp pushl -4(%ecx) .LCFI3: xorl %eax, %eax pushl %ebp .LCFI4: movl %esp, %ebp .LCFI5: pushl %ecx .LCFI6: popl %ecx popl %ebp leal -4(%ecx), %esp ret .LFE3: .size main, .-main .ident "GCC: (GNU) 4.1.2 (Gentoo 4.1.2 p1.1)" .section .note.GNU-stack,"",@progbits
#12
Posted 05 January 2009 - 07:04 AM
Thanks to all of you for the discussion.
I have a query on the second question.
So, in bottom-up approach, we first do create the lower level functions which are implemented thereafter. So, if I make use of a structure in C, is this a bottom-up approach? Dont we use this method in procedural languages?
I have a query on the second question.
Quote
Top-down programming means you start with high level material, and coding as if the low-level material (for example, some complex functions) have already been coded. Once done, you code the more complex material, repeating the process until you are done coding everything you have used. Bottom-up is the exact opposite approach; you code the complex functions and such first, then get higher and higher level until you get to your main implementation which should essentially use all the low-level code you have already pumped out. This is seen more frequently in object-oriented programming, and OOP is seen more frequently in C++ rather that C (no one likes to deal with structs when classes can be used and are more convenient). So your statement, although not correct, is generally true. You see bottom-up more often in C++ as opposed to C.
So, in bottom-up approach, we first do create the lower level functions which are implemented thereafter. So, if I make use of a structure in C, is this a bottom-up approach? Dont we use this method in procedural languages?


Sign In
Create Account


Back to top









