63

Possible Duplicate:
Is there a performance difference between i++ and ++i in C++?

Is there a reason some programmers write ++i in a normal for loop instead of writing i++?

Community
  • 1
  • 1
Ismail Marmoush
  • 13,140
  • 25
  • 80
  • 114

9 Answers9

136

++i is slightly more efficient due to its semantics:

++i;  // Fetch i, increment it, and return it
i++;  // Fetch i, copy it, increment i, return copy

For int-like indices, the efficiency gain is minimal (if any). For iterators and other heavier-weight objects, avoiding that copy can be a real win (particularly if the loop body doesn't contain much work).

As an example, consider the following loop using a theoretical BigInteger class providing arbitrary precision integers (and thus some sort of vector-like internals):

std::vector<BigInteger> vec;
for (BigInteger i = 0; i < 99999999L; i++) {
  vec.push_back(i);
}

That i++ operation includes copy construction (i.e. operator new, digit-by-digit copy) and destruction (operator delete) for a loop that won't do anything more than essentially make one more copy of the index object. Essentially you've doubled the work to be done (and increased memory fragmentation most likely) by simply using the postfix increment where prefix would have been sufficient.

Drew Hall
  • 28,429
  • 12
  • 61
  • 81
92

For integers, there is no difference between pre- and post-increment.

If i is an object of a non-trivial class, then ++i is generally preferred, because the object is modified and then evaluated, whereas i++ modifies after evaluation, so requires a copy to be made.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 18
    Although the same code is generated with integers, because of the second paragraph, it's probably a good idea to go with `++i` for all types, so that you are in the habit of using it for all types. – SingleNegationElimination Nov 23 '10 at 22:45
  • 2
    @Token: I agree in principle. However, `i++` is somewhat idiomatic in C code; if you regularly use both languages, it can get confusing... – Oliver Charlesworth Nov 23 '10 at 22:49
  • Pardon my ignorance here, but this sure sounds silly. Imagine that `i` is an instance of some class that overloads the increment operator. Are you saying that if I were to simply post-increment (not in a loop control statement, but rather just increment it) (i.e. `i++;`), that the compiler wouldn't be able to see that I'm not *doing* anything with the return value, and automatically re-write that to be `++i`? – Jim Mischel Nov 23 '10 at 22:54
  • 4
    @Jim: the compiler has to call the relevant operator overload (`operator++()` or `operator++(int)` for preincrement and postincrement respectively). If they're actually equivalent, and if the call is inlined, and if the copies involved are all removed by the optimizer, then the emitted code may end up the same - try it. But the compiler certainly can't replace one with the other solely on the basis that the result is unused. I don't especially care, because I write `++i` for clarity (as I perceive it). "increment i" -> "++i". – Steve Jessop Nov 23 '10 at 23:04
  • 2
    @Jim Mischel: The compiler can see that the return value isn't being used, but it has no reason to expect that ++i and i++ have the same semantics modulo the copy. So it has to call the version that the programmer asked for. – Drew Hall Nov 23 '10 at 23:06
  • egads, it's been so long, I forgot that post-increment and pre-increment are two entirely different operators in C++, which can be overloaded independently. Thanks. – Jim Mischel Nov 23 '10 at 23:09
  • The second reason is a good reason to always use the prefix ++. The reason being that code is always being modified, and what is an integer (pointer) today will become an iterator tomorrow. Thus you want to be able to change the type without having to go through all the code and change its usage. – Martin York Nov 24 '10 at 00:07
  • @Oli: Heavens forbid that code being idiomatic in C would be a good reason to use it in C++ as well! – sbi Nov 24 '10 at 06:12
10

++i is a pre-increment; i++ is post-increment.
The downside of post-increment is that it generates an extra value; it returns a copy of the old value while modifying i. Thus, you should avoid it when possible.

Richard
  • 3,316
  • 30
  • 41
5

With integers, it's preference.

If the loop variable is a class/object, it can make a difference (only profiling can tell you if it's a significant difference), because the post-increment version requires that you create a copy of that object that gets discarded.

If creating that copy is an expensive operation, you're paying that expense once for every time you go through the loop, for no reason at all.

If you get into the habit of always using ++i in for loops, you don't need to stop and think about whether what you're doing in this particular situation makes sense. You just always are.

bgporter
  • 35,114
  • 8
  • 59
  • 65
3

No compiler worth its weight in salt will run differently between

for(int i=0; i<10; i++)

and

for(int i=0;i<10;++i)

++i and i++ have the same cost. The only thing that differs is that the return value of ++i is i+1 whereas the return value of i++ is i.

So for those prefering ++i, there's probably no valid justification, just personal preference.

EDIT: This is wrong for classes, as said in about every other post. i++ will generate a copy if i is a class.

rtpg
  • 2,419
  • 1
  • 18
  • 31
  • 1
    That's probably true for int-like indices, but not generally true for iterators and other objects that might act as indices. – Drew Hall Nov 23 '10 at 22:43
  • doesn't i++ and ++i call the same operator? – rtpg Nov 23 '10 at 22:45
  • 1
    No, `++i` calls `i.operator++()` and `i++` calls `i.operator(int)`. See [my answer](http://stackoverflow.com/questions/4261708/i-or-i-in-for-loops/4261836#4261836) for implementation details. – fredoverflow Nov 23 '10 at 22:57
  • 100% agreed with what @FredOverflow said. Think of it this way, there is no reason to write i++, but there might be a reason to write ++i. – Ajk_P Sep 15 '14 at 19:43
3

There is a reason for this: performance. i++ generates a copy, and that's a waste if you immediately discard it. Granted, the compiler can optimize away this copy if i is a primitive, but it can't if it isn't. See this question.

Community
  • 1
  • 1
wilhelmtell
  • 57,473
  • 20
  • 96
  • 131
  • 1
    This is disingenous. In almost every single case, the performance of `++i` and `i++` is exactly the same. – John Dibling Nov 23 '10 at 22:42
  • 3
    @John: Not disingenuous at all. For iterator objects, the compiler has no reason to even expect some sort of equivalence between prefix and postfix increment (the class designer can make them perform arbitrarily different actions)--it must call the postfix form (with resulting copy). For heavyweight iterators and otherwise lightweight loops, the performance hit can be significant. As an example, what if i is not an int or a std::vector::iterator, but instead a BigInteger or equivalent. The copy is unneccessary and should just be avoided, period. – Drew Hall Nov 23 '10 at 23:01
  • 1
    @Drew: In that case, the programmer is going to know it (or should, anyway) and my disclaimer that "if you have to ask, it doesnt matter" wont apply. The question was about "normal for loop"s. Performance has nothing to do with it. Its all about personal style. – John Dibling Nov 23 '10 at 23:11
  • 1
    John Dibling: "Normal for loops" typically involve iterators. – M2tM Nov 23 '10 at 23:17
  • 1
    @John: Perhaps. I guess I just consider it a good habit to be in--there is no downside to always writing ++i, but there is (sometimes) a downside to writing i++. – Drew Hall Nov 23 '10 at 23:22
  • @Drew: I don't dispute it being a good habit to be in. In fact I do the same thing. – John Dibling Nov 23 '10 at 23:36
2

As others have already noted, pre-increment is usually faster than post-increment for user-defined types. To understand why this is so, look at the typical code pattern to implement both operators:

Foo& operator++()
{
    some_member.increase();
    return *this;
}

Foo operator++(int dummy_parameter_indicating_postfix)
{
    Foo copy(*this);
    ++(*this);
    return copy;
}

As you can see, the prefix version simply modifies the object and returns it by reference.

The postfix version, on the other hand, must make a copy before the actual increment is performed, and then that copy is copied back to the caller by value. It is obvious from the source code that the postfix version must do more work, because it includes a call to the prefix version: ++(*this);

For built-in types, it does not make any difference as long as you discard the value, i.e. as long as you do not embed ++i or i++ in a larger expression such as a = ++i or b = i++.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • 2
    I think "must make a copy" is overstating it a bit. If the result is unused, and the operator and the copy constructor can both be completely inlined, as is commonly the case with iterators, then it should be a sitting duck for the optimizer to remove `copy` entirely - unused value with no side-effects. `++i` does save you wondering whether the optimization was successful, and more importantly it just *obviously makes more sense* ;-) – Steve Jessop Nov 23 '10 at 23:11
1

when you use postfix it instantiates on more object in memory. Some people say that it is better to use suffix operator in for loop

Yevhen
  • 1,897
  • 2
  • 14
  • 25
-1

Personal preference.

Usually. Sometimes it matters but, not to seem like a jerk here, but if you have to ask, it probably doesn't.

John Dibling
  • 99,718
  • 31
  • 186
  • 324