Is there any performance difference between using something like
for(int i = 0; i < 10; i++) { ... }
and
for(int i = 0; i < 10; ++i) { ... }
or is the compiler able to optimize in such a way that they are equally fast in the case where they are functionally equivalent?
Edit: This was asked because I had a discussion with a co-worker about it, not because I think its a useful optimization in any practical sense. It is largely academic.
++i is sometimes faster than, and is never slower than, i++. For intrinsic types like int, it doesn't matter: ++i and i++ are the same speed. 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.
In the prefix version (i.e., ++i), the value of i is incremented, and the value of the expression is the new value of i. So basically it first increments then assigns a value to the expression. In the postfix version (i.e., i++), the value of i is incremented, but the value of the expression is the original value of i.
There is no difference in your case. --i is pre-decrement and i-- is post-decrement.
These two are exactly the same. It's just two different ways of writing the same thing. i++ is just a shortcut for i += 1 , which itself is a shortcut for i = i + 1 . These all do the same thing, and it's just a question of how explicit you want to be.
There is no difference in the generated intermediate code for ++i and i++ in this case. Given this program:
class Program { const int counter = 1024 * 1024; static void Main(string[] args) { for (int i = 0; i < counter; ++i) { Console.WriteLine(i); } for (int i = 0; i < counter; i++) { Console.WriteLine(i); } } }
The generated IL code is the same for both loops:
IL_0000: ldc.i4.0 IL_0001: stloc.0 // Start of first loop IL_0002: ldc.i4.0 IL_0003: stloc.0 IL_0004: br.s IL_0010 IL_0006: ldloc.0 IL_0007: call void [mscorlib]System.Console::WriteLine(int32) IL_000c: ldloc.0 IL_000d: ldc.i4.1 IL_000e: add IL_000f: stloc.0 IL_0010: ldloc.0 IL_0011: ldc.i4 0x100000 IL_0016: blt.s IL_0006 // Start of second loop IL_0018: ldc.i4.0 IL_0019: stloc.0 IL_001a: br.s IL_0026 IL_001c: ldloc.0 IL_001d: call void [mscorlib]System.Console::WriteLine(int32) IL_0022: ldloc.0 IL_0023: ldc.i4.1 IL_0024: add IL_0025: stloc.0 IL_0026: ldloc.0 IL_0027: ldc.i4 0x100000 IL_002c: blt.s IL_001c IL_002e: ret
That said, it's possible (although highly unlikely) that the JIT compiler can do some optimizations in certain contexts that will favor one version over the other. If there is such an optimization, though, it would likely only affect the final (or perhaps the first) iteration of a loop.
In short, there will be no difference in the runtime of simple pre-increment or post-increment of the control variable in the looping construct that you've described.
If you're asking this question, you're trying to solve the wrong problem.
The first question to ask is "how to I improve customer satisfaction with my software by making it run faster?" and the answer is almost never "use ++i instead of i++" or vice versa.
From Coding Horror's post "Hardware is Cheap, Programmers are Expensive":
Rules of Optimization:
Rule 1: Don't do it.
Rule 2 (for experts only): Don't do it yet.
-- M.A. Jackson
I read rule 2 to mean "first write clean, clear code that meets your customer's needs, then speed it up where it's too slow". It's highly unlikely that ++i
vs. i++
is going to be the solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With