This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Preincrement faster than postincrement in C++ - true? If yes, why is it?
Is there a performance difference between i++ and ++i in C++?
I got told that when using the STL and it's iterators, I should always use ++iter instead of iter++.
I quote:
Because it can only be faster, never slower
Is this true?
Yes. It is true in general. The postfix increment is burdened with the task of preserving and returning the old value of the iterator. That takes time and effort, which is what generally makes it slower.
It is generally true for all overloaded increment/decrement operators that implement the traditional pre/post semantics.
This topic is beaten to death. Do a search here on "prefix postfix" for a large number of more detailed explanations.
You can see in this Example that was created a temp, in postfix... This more slowly than prefix, where is no created advanced object
// Define prefix increment operator.
Point& Point::operator++()
{
_x++;
_y++;
return *this;
}
// Define postfix increment operator.
Point Point::operator++(int)
{
Point temp = *this;
++*this;
return temp;
}
++iter more faster than iter++., because don't created copy of object
Related
This question already has answers here:
Is there a performance difference between i++ and ++i in C++?
(20 answers)
Closed 6 years ago.
I usually think that preincrement is more efficient than postincrement in C++. But when I read the book Game Engine Architecture(2nd ed.) recently, there is a section says that postincrement is prefered than preincrement in for loop. Because, as I quote, "preincrement introduces a data dependency into your code -- the CPU must wait for the increment operation to be completed before its value can be used in the expression." Is this true? (It is really subverted my idea about this problem.)
Here is the quote from the section in case you are interested:
5.3.2.1 Preincrement versus Postincrement
Notice in the above example that we are using C++’s postincrement operator,
p++, rather than the preincrement operator, ++p. This is a subtle but sometimes important optimization. The preincrement operator increments the contents of the variable before its (now modified) value is used in the expression. The postincrement operator increments the contents of the variable after it has been used. This means that writing ++p introduces a data dependency into your code -- the CPU must wait for the increment operation to be completed before its value can be used in the expression. On a deeply pipelined CPU, this introduces a stall. On the other hand, with p++ there is no data dependency. The value of the variable can be used immediately, and the increment operation can happen later or in parallel with its use. Either way, no stall is introduced into the pipeline.
Of course, within the “update” expression of a for loop (for(init_expr;
test_expr; update_expr) { ... }), there should be no difference between
pre- and postincrement. This is because any good compiler will recognize that
the value of the variable isn’t used in update_expr. But in cases where the
value is used, postincrement is superior because it doesn’t introduce a stall
in the CPU’s pipeline. Therefore, it’s good to get in the habit of always using
postincrement, unless you absolutely need the semantics of preincrement.
Edit: Add "the above example".
void processArray(int container[], int numElements)
{
int* pBegin = &container[0];
int* pEnd = &container[numElements];
for (int* p = pBegin; p != pEnd; p++)
{
int element = *p;
// process element...
}
}
void processList(std::list<int>& container)
{
std::list<int>::iterator pBegin = container.begin();
std::list<int>::iterator pEnd = container.end();
std::list<inf>::iterator p;
for (p = pBegin; p != pEnd; p++)
{
int element = *p;
// process element...
}
}
pre-increment introduces a data dependency into your code -- the CPU must wait for the increment operation to be completed before its value can be used in the expression."
Is this true?
It is mostly true - although perhaps overly strict. Pre increment doesn't necessarily introduce a data dependency - but it can.
A trivial example for exposition:
a = b++ * 2;
Here, the increment can be executed in parallel with the multiplication. The operands of both the increment and the multiplication are immediately available and do not depend on the result of either operation.
Another example:
a = ++b * 2;
Here, the multiplication must be executed after the increment, because one of the operands of the multiplication depends on the result of the increment.
Of course, these statements do slightly different things, so the compiler might not always be able to transform the program from one form to the other while keeping the semantics the same - which is why using the post-increment might make a slight difference in performance.
A practical example, using a loop:
for(int i= 0; arr[i++];)
count++;
for(int i=-1; arr[++i];) // more typically: (int i=0; arr[i]; ++i;)
count++;
One might think that the latter is necessarily faster if they reason that "post-increment makes a copy" - which would have been very true in the case of non-fundamental types. However, due to the data dependency (and because int is a fundamental type with no overload function for increment operators), the former can theoretically be more efficient. Whether it actually is depends on the CPU architecture, and the ability of the optimizer.
For what it's worth - in a trivial program, on x86 arch, using g++ compiler with optimization enabled, the above loops had identical assembly output, so they are perfectly equivalent in that case.
Rules of thumb:
If the counter is a fundamental type and the result of increment is not used, then it makes no difference whether you use post/pre-increment.
If the counter is not a fundamental type and the result of the increment is not used and optimizations are disabled, then pre-increment may be more efficient. With optimizations enabled, there is usually no difference.
If the counter is a fundamental type and the result of increment is used, then post-increment can theoretically be marginally more efficient - in some CPU architecture - in some context - using some compiler.
If the counter is not a fundamental type and the result of the increment is used, then pre-increment is typically faster than post-increment. Also, see R Sahu's answer regarding this case.
One point of data from my experience.
Changing a post-increment to a pre-increment of a std::map::iterator in for loops resulted in noticeable savings in a core algorithm at my work.
In general, when icrementing an iterator that is a class, i.e. it is not a pointer, you should notice savings when using the pre-increment operator. The reason for it is that the pre-increment operator function changes the object in place while the post increment operator function usually involves creation of a temporary object.
A pre-increment operator is usually implemented as:
typename& typename::operator++()
{
// Change state
...
// Return the object
return *this;
}
while a post-increment operator is usually implemented as:
typename typename::operator++(int)
{
// Create a temporary object that is a copy of the current object.
typename temp(*this):
// Change state of the current object
...
// Return the temporary object.
return temp;
}
Is it valid to do this on an input iterator *it++ ?
I understand the code as follow, that it dereference the iterator and gives me the value and then step one ahead.
In the c++ reference the * operator is lower than the postfix operator: http://en.cppreference.com/w/cpp/language/operator_precedence
But I read this style is bad practice. Why?
Is it valid to do this on an input iterator *it++?
Yes, that is valid. The iterator will be incremented, its previous value will be returned, and you will dereference that returned iterator.
But I read this style is bad practice. Why?
Consider these two implementations I've just pulled out of some graph code I wrote a while back:
// Pre-increment
BidirectionalIterator& operator++()
{
edge = (edge->*elem).next;
return *this;
}
// Post-increment
BidirectionalIterator operator++(int)
{
TargetIterator oldval(list, edge);
edge = (edge->*elem).next;
return oldval;
}
Notice that for post-increment, I need to first construct a new iterator to store the previous value which will be returned.
If it's simple and clear to write your program to make use of pre-increment, there may be better performance, less work for the compiler to do, or both.
Just don't go crazy on this (for example, rewriting all your loops)! That would likely be micro-optimization. However, the reason people say it's good practice is that if you get into a habit of using pre-increment as default then you get (potentially) better performance by default.
This question already has answers here:
Is there a performance difference between i++ and ++i in C++?
(20 answers)
Closed 6 years ago.
I usually think that preincrement is more efficient than postincrement in C++. But when I read the book Game Engine Architecture(2nd ed.) recently, there is a section says that postincrement is prefered than preincrement in for loop. Because, as I quote, "preincrement introduces a data dependency into your code -- the CPU must wait for the increment operation to be completed before its value can be used in the expression." Is this true? (It is really subverted my idea about this problem.)
Here is the quote from the section in case you are interested:
5.3.2.1 Preincrement versus Postincrement
Notice in the above example that we are using C++’s postincrement operator,
p++, rather than the preincrement operator, ++p. This is a subtle but sometimes important optimization. The preincrement operator increments the contents of the variable before its (now modified) value is used in the expression. The postincrement operator increments the contents of the variable after it has been used. This means that writing ++p introduces a data dependency into your code -- the CPU must wait for the increment operation to be completed before its value can be used in the expression. On a deeply pipelined CPU, this introduces a stall. On the other hand, with p++ there is no data dependency. The value of the variable can be used immediately, and the increment operation can happen later or in parallel with its use. Either way, no stall is introduced into the pipeline.
Of course, within the “update” expression of a for loop (for(init_expr;
test_expr; update_expr) { ... }), there should be no difference between
pre- and postincrement. This is because any good compiler will recognize that
the value of the variable isn’t used in update_expr. But in cases where the
value is used, postincrement is superior because it doesn’t introduce a stall
in the CPU’s pipeline. Therefore, it’s good to get in the habit of always using
postincrement, unless you absolutely need the semantics of preincrement.
Edit: Add "the above example".
void processArray(int container[], int numElements)
{
int* pBegin = &container[0];
int* pEnd = &container[numElements];
for (int* p = pBegin; p != pEnd; p++)
{
int element = *p;
// process element...
}
}
void processList(std::list<int>& container)
{
std::list<int>::iterator pBegin = container.begin();
std::list<int>::iterator pEnd = container.end();
std::list<inf>::iterator p;
for (p = pBegin; p != pEnd; p++)
{
int element = *p;
// process element...
}
}
pre-increment introduces a data dependency into your code -- the CPU must wait for the increment operation to be completed before its value can be used in the expression."
Is this true?
It is mostly true - although perhaps overly strict. Pre increment doesn't necessarily introduce a data dependency - but it can.
A trivial example for exposition:
a = b++ * 2;
Here, the increment can be executed in parallel with the multiplication. The operands of both the increment and the multiplication are immediately available and do not depend on the result of either operation.
Another example:
a = ++b * 2;
Here, the multiplication must be executed after the increment, because one of the operands of the multiplication depends on the result of the increment.
Of course, these statements do slightly different things, so the compiler might not always be able to transform the program from one form to the other while keeping the semantics the same - which is why using the post-increment might make a slight difference in performance.
A practical example, using a loop:
for(int i= 0; arr[i++];)
count++;
for(int i=-1; arr[++i];) // more typically: (int i=0; arr[i]; ++i;)
count++;
One might think that the latter is necessarily faster if they reason that "post-increment makes a copy" - which would have been very true in the case of non-fundamental types. However, due to the data dependency (and because int is a fundamental type with no overload function for increment operators), the former can theoretically be more efficient. Whether it actually is depends on the CPU architecture, and the ability of the optimizer.
For what it's worth - in a trivial program, on x86 arch, using g++ compiler with optimization enabled, the above loops had identical assembly output, so they are perfectly equivalent in that case.
Rules of thumb:
If the counter is a fundamental type and the result of increment is not used, then it makes no difference whether you use post/pre-increment.
If the counter is not a fundamental type and the result of the increment is not used and optimizations are disabled, then pre-increment may be more efficient. With optimizations enabled, there is usually no difference.
If the counter is a fundamental type and the result of increment is used, then post-increment can theoretically be marginally more efficient - in some CPU architecture - in some context - using some compiler.
If the counter is not a fundamental type and the result of the increment is used, then pre-increment is typically faster than post-increment. Also, see R Sahu's answer regarding this case.
One point of data from my experience.
Changing a post-increment to a pre-increment of a std::map::iterator in for loops resulted in noticeable savings in a core algorithm at my work.
In general, when icrementing an iterator that is a class, i.e. it is not a pointer, you should notice savings when using the pre-increment operator. The reason for it is that the pre-increment operator function changes the object in place while the post increment operator function usually involves creation of a temporary object.
A pre-increment operator is usually implemented as:
typename& typename::operator++()
{
// Change state
...
// Return the object
return *this;
}
while a post-increment operator is usually implemented as:
typename typename::operator++(int)
{
// Create a temporary object that is a copy of the current object.
typename temp(*this):
// Change state of the current object
...
// Return the temporary object.
return temp;
}
I am currently implementing an iterator for an internal data structure and had a look at how QVector implements its iterator. I don't understand why the QTypedArrayData::iterator implements its ++ and -- operators like:
T *i;
inline iterator &operator++() { ++i; return *this; }
inline iterator &operator--() { i--; return *this; }
What I don't understand is the discrepancy between the two: Why does it use a postfix decrement operator?
Thanks for any clarification!
Your lack of understanding implies an expectation that there is any practical difference between the two, and, that the coding was purposefully done that way. Such expectation is reasonable, but incorrect. You can write these operations either way, and they'll work just the same. It might matter on non-POD types that are expensive to copy/move, but that's not the case here. And it used to matter 15-20 years ago on the poor compilers of that era. Thankfully we don't have to deal with VS6 anymore :)
This question already has answers here:
Why use ++i instead of i++ in cases where the value is not used anywhere else in the statement?
(7 answers)
Technical reasons behind formatting when incrementing by 1 in a 'for' loop?
(31 answers)
Closed 9 years ago.
I have a question about writing loops. I always begin with
(int i=0; i<10; i++)
But I see many experts begin with
(int i=0; i<10; ++i)
Is there there any real difference, or they are same?
Of course, I know the difference between pre-increment and post-increment. I mean which one I should use when writing the loop? or it depends.
Thanks!
There is no difference among the two. Pre increment and post increment are the only
difference.
The difference between i++ and ++i is the value of the expression.
The value i++ is the value of i before the increment. The value of ++i is the value of i after the increment.
However in your loop it does not make any difference.
int i = 0;
00000088 xor edx,edx
0000008a mov dword ptr [ebp-40h],edx
i++;
0000008d inc dword ptr [ebp-40h]
++i;
00000090 inc dword ptr [ebp-40h]
As you can see it does not make any difference in performance but in certain situations you might want to increment a number right after a sequence point or before it.
In C++ ++i is an l-value, but i++ is not.
In C++ there is a difference. While the prefix operator will return a reference to the value, the postfix operator will return a copy and therefore is slower than the prefix operator.
The main difference between pre- and post-incrementing lies in the return value.
Post-incrementing returns the value which has been present before the variable has been increased, essentially creating a copy of the old value. Pre-incrementing returns a reference to the new value, thereby avoiding the creation of a temporary variable.
Generally speaking it does not make a difference and is mostly a matter of taste, but in certain cases where memory is short the pre-increment option might be more useful. I also read that the post-increment version is supposed to be slower (as it creates a new temporary variable) but I have not found any conclusive proof of that
Preincrement is generally preferred because while it makes no difference for primitive types it may be faster for iterators as preincrement doesn't have to return a copy of its old value.
Since preincrement is sometimes faster (with non primitive types like iterators) it is a good habit to get into even where it makes no performance difference which is why many people recommend it. This is item 28 in C++ Coding Standards for example.