6

Exact Duplicate:

In C# what is the difference between myint++ and ++myint?

Hopefully this is not too general or weird of a question. Also, couldn't find it on Google, don't whether this is just too dumb of a question or whether I fail at Google.

So, I forget where I read this from but, it said that using '++x' (or whatever other variable) is somehow more optimized or whatever you might call this than, 'x++'.

So, is this just a looks thing or is one truly faster? Like, they do the exact same thing so, that is why I am asking.

Community
  • 1
  • 1
Mashew
  • 561
  • 1
  • 5
  • 10

10 Answers10

23

They're doing different things. The first is pre-increment, and the second is post-increment. If you use either alone on a line, you won't notice the difference. But if you do (for instance):

a = x++

or

a = ++x

you will. With post-increment, you get the value, then increment. With pre-increment, you increment, then get the value. See http://en.wikipedia.org/wiki/++#Use_in_programming_languages for a brief explanation (they use JS as an example, but it applies equally to C#)

EDIT: By popular demand (and to refute a couple exaggerations), here's a little about performance with primitives in C++. Take this example program:

int main()
{
    int a;
    int x = 14, y = 19;
    a = x++;    
    a = ++y;    
}

It compiles (g++, just -S) to the below on x86. I have removed irrelevant lines. Let's look at what's happening and see if unnecessary duplicates are being made.:

        # Obvious initialization.
        movl    $14, -12(%ebp) 
        movl    $19, -16(%ebp)

        movl    -12(%ebp), %eax # This is moving "old x" to the accumulator.
        movl    %eax, -8(%ebp) # Moving accumulator to a.
        addl    $1, -12(%ebp) # Increment x (post-increment).

        addl    $1, -16(%ebp) # Increment y (pre-increment)
        movl    -16(%ebp), %eax # Move "new y" to accumulator.
        movl    %eax, -8(%ebp) # Move accumulator to a.

We're done.

As you can see, in this example, the exact same operations are required in each case. Exactly 2 movl, and 1 addl. The only difference is the order (surprised?). I think this is fairly typical of examples where the increment statement's value is used at all.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • 5
    I thought the question was about performance and not about functionality. I wonder why Mashew accepted your answer. – Vadim May 14 '09 at 01:09
  • 1
    Well, the question was clearly confused, as indicated by "they do the exact same thing" – Matthew Flaschen May 14 '09 at 01:20
  • Re the assembly (and comments about exaggeration): The compiler is certainly free to optimise the generated code however it likes, and in the case of primitive types, that's trivial. In the case of inlined overloaded operators (or even non-inlined ones, with whole program analysis), optimising postincrement ++ to have the same performance to preincrement ++ is possible too. But, in contexts where it doesn't matter whether pre or post is to be used, I'd say that it's prudent not to gratuitously use the version that's "sometimes" slower. – C. K. Young May 14 '09 at 01:39
  • It's certainly worth being aware of the performance issue when dealing with overloaded operators, and you have a very valid point there. But I just wanted to clear things up regarding primitives. – Matthew Flaschen May 14 '09 at 01:43
  • Much better answer. Great job. Definitely +1. – Vadim May 14 '09 at 01:45
  • @Matthew: I agree that with primitives, the difference is not worth thinking about. That means in Java and C#, it's not worth thinking about, full stop. In C++, when using primitive types only, again it doesn't matter. But when writing generic code (i.e., code which doesn't know/care about the types of its inputs), it's easier to consistently use preincrement, than to test whether the inputs are primitive or not. :-D – C. K. Young May 14 '09 at 01:47
  • 1
    In other words, I think we're agreeing on the same thing, pretty much. :-P – C. K. Young May 14 '09 at 01:48
  • 1
    Wait, but C# does have ++ overloading from what I understand (though I've never used it). But I agree :) we're mostly in agreement. – Matthew Flaschen May 14 '09 at 01:58
  • 1
    When I wrote that, I didn't know that C# has overloaded ++ (I do know it has overloaded operators in general). I thought about correcting my post when I saw your comment to the other post, though. Well, let's do it here, retrospectively. :-) – C. K. Young May 14 '09 at 02:04
10

If you are optimizing at this level you are wasting time. There are surely some loops in your program that could get faster.

jon skulski
  • 2,305
  • 3
  • 18
  • 27
  • I disagree... its a simple optimization that once learned could be used through all future code without little effort. It may not be worth doing on one program to speed it up... but amortize the benefit over all future work, and it may be worth while to take the two seconds to see if it matters. – Ape-inago May 31 '09 at 17:42
  • 2
    A good point, that it propagates the value. I doubt that this would provide noticeable speed benefits in most cases. I also argue that when writing in a language as high as C#, then x++ vs. ++x is semantic. – jon skulski Jun 01 '09 at 18:23
5

Well, the preincrement operation ("++x") returns the result of the variable after the increment has been done, whereas the postincrement operation ("x++") returns the result of the variable before the increment has been done. The compiler COULD (and strong emphasis on COULD) optimize easier using the preincrement (because only one value is effectively being used; in the postincrement case, there are two values; the value of the variable before the increment, and the value of the variable after; the compiler might be able to optimize the preincrement to use the storage that contains the variable itself).

Note that this is very much theoretical; it very much depends on your compiler optimization. In most situations, and for most purposes, they'll effectively be equivalently efficient.

Paul Sonier
  • 38,903
  • 3
  • 77
  • 117
3

In C# (since that's mentioned in the question tags), the two shouldn't be too different, if used standalone.

In C++, ++x is to be preferred over x++, because (for classes with overloaded operators), best practice is for post-increment to be implemented in terms of the pre-increment.

// pre-increment (note, return by reference)
T& operator++() {
    // ... do its thing
}

// post-increment (note, return by value)
T operator++(int) {
    T saved(*this);
    ++*this;  // or: operator++();
    return saved;
}
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • Do you have a source for the latter statement? I find it highly unlikely. Also, it's important to note they do make a difference when not used stand-alone. – Matthew Flaschen May 14 '09 at 00:58
  • 1
    http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.15 – C. K. Young May 14 '09 at 01:00
  • Usual implementation of postincrement: T operator++(int) {T result(*this); operator++(); return result;} – C. K. Young May 14 '09 at 01:03
  • Are you referring to "For class types like iterators or the previous FAQ's Number class, ++i very well might be faster than i++ since the latter might make a copy of the this object." That can only apply for objects, and only when there is operator overloading. It does not indicate x++ is /generally/ implemented in terms of ++x. – Matthew Flaschen May 14 '09 at 01:06
  • @Matthew: C++ allows operator overloading, where you can define the behaviour of ++ (both pre- and post-increment). Because of this, for consistency, standard practice is that one is implemented in terms of the other. Because the post-increment must return the old value, it's usually done by saving the old value, calling the pre-increment operator, then returning the saved value. Hope this helps. :-) – C. K. Young May 14 '09 at 01:06
  • @Matthew: Sure, I'll edit my post to clarify this. – C. K. Young May 14 '09 at 01:06
3

It's not a matter of optimization, it's a matter of functionality.

Explained here... In C# what is the difference between myInt++ and ++myInt?

Community
  • 1
  • 1
Steve Dignan
  • 8,230
  • 6
  • 30
  • 34
3

x++ will increment x, but return its old value. ++x increments x and returns the new value. The difference is that x++ needs to declare a hidden temp variable to store the old value.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
  • So, really ++x would be the nicer thing to do overall but, it really doesn't do much on the grand scale of the code? – Mashew May 14 '09 at 01:04
  • @Mashew: Yeah, I would agree with that. ++x is able to produce a faster increment on some compilers, but if that's your bottleneck, you have some pretty tight code. I personally never worry about it. – Bill the Lizard May 14 '09 at 11:45
3

Here's a good summary of pre- and post-increment.

The summary is that pre-increment, ++x, is simpler and should maybe be preferred. However, in practice, I doubt it makes a significant difference.

I think it's more important to understand the difference in their function rather than worry about their speed. Use the write one for the write job.

Naaff
  • 9,213
  • 3
  • 38
  • 43
2

I thought it was an interesting question. I didn't know that there's a performance difference when use an increment operator either from right side of a variable or left. Apparently there's in C++ (thanks Chris Jester-Young, +1 for you).

I decided for my self to see what CLR does with this operator. I created two functions:

private int IncrementRight(int n)
{
    return n++;
}

private int IncrementLeft(int n)
{
    return ++n;
}

I looked at the compiled code in Reflector. IL looks almost identical; the difference is only in order of OpCodes.

Here's the IL for both methods:

.method private hidebysig instance int32 IncrementLeft(int32 n) cil managed
{
    .maxstack 8
    L_0000: ldarg.1 
    L_0001: ldc.i4.1 
    L_0002: add 
    L_0003: dup 
    L_0004: starg.s n
    L_0006: ret 
}


.method private hidebysig instance int32 IncrementRight(int32 n) cil managed
{
    .maxstack 8
    L_0000: ldarg.1 
    L_0001: dup 
    L_0002: ldc.i4.1 
    L_0003: add 
    L_0004: starg.s n
    L_0006: ret 
}

Therefore, my conclusion is that there's no difference in C# when you use increment operators.

Vadim
  • 21,044
  • 18
  • 65
  • 101
  • And if you don't compile in debug mode? – Guffa May 14 '09 at 01:26
  • Of course, in this case there's a behavior difference (the returned value will depend on which you use), but no performance difference. It's similar to the x86 example I posted above. – Matthew Flaschen May 14 '09 at 01:39
  • @Guffa, thanks for pointing out that it was a debug code. I modified the answer to show code compiled in release build. The answer is still the same. No difference. – Vadim May 14 '09 at 01:42
  • 1
    Of course it's important to keep in mind this applies for primitives. ++ can also be overloaded in C# (http://www.csharphelp.com/archives/archive135.html), in which case one should bear Chris's comments in mind. – Matthew Flaschen May 14 '09 at 01:46
1

Pre vs Post increment (fogcreek)

Preincrement is more efficient than postincrement, because for postincrement the object must increment itself and then return a temporary containing its old value. Note that this is true even for builtins like int!

The temporary thing is what makes the difference.

Larger the object the worse off the memory usage is.

Correct me if I'm wrong please.

lsl
  • 4,371
  • 3
  • 39
  • 54
  • 1
    It's certainly not true that a primitive "returns anything" in an increment operation. There is no function, no object, no return, period. – Matthew Flaschen May 14 '09 at 01:11
  • @Matthew: I believe Lou is talking about overloaded increment operators in C++. As is my post. :-D – C. K. Young May 14 '09 at 01:13
  • Yes, but he said, "Note that this is true even for builtins like int". It is not true (obviously) that a built-in returns anything. – Matthew Flaschen May 14 '09 at 01:21
  • @Matthew: Point taken. :-) However, from the compiler's perspective, it is possible to implement most operators (even for primitives) as (inline) functions; certainly, it's reasonable to logically think of all operators as functions of a sort, even if not a "formal" function with parameters and function body and the lot. – C. K. Young May 14 '09 at 01:26
  • It is certainly possible, but in this case I think unhelpful. I have added real assembly code to my answer to try to clarify. – Matthew Flaschen May 14 '09 at 01:35
0

Used by itself (where the return value is not used), the compiler should be smart enough to produce the same code for both.

And, you should try to use it on it's own, unless you specifically need the post-increment or pre-increment behaviour for something. I have found that code like this:

r[ofs] = *(p++);

is somewhat slower than:

r[ofs] = *p;
p++;

So, if in doubt keep it simple and break it apart on separate lines if you are in a tight loop and need the litte extra.

Edit:
Changed the example code to some actual code where I observed this.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Guffa, I did a quick test with a one-element array. As expected, it was equivalent. There were 3 movl and 1 addl either way. I would be interested if there were a specific example where the first were slower. – Matthew Flaschen May 14 '09 at 01:56
  • I replaced the example code with some actual code where I have observed a difference. It's part of an image sharpening routine, so it's quite a long loop. – Guffa May 14 '09 at 03:19