5

I never saw a tutorial or some lecture, which showed a classic for-loop witout the post-increment-order.

for (int i=0; i<array.length; i++) {}

If you use POST-increment, the variable "i" will be cached, before it will get incremented! But this makes no sense, because the command ends directly.

In my opinion, this makes more sense:

for (int i=0; i<array.length; ++i) {}

If you didn't understand until now, I go a bit further (sry for my english):

In the first loop:

  1. Cache the actual value of i. (note: no move between, so no reason to do this)
  2. Increment i
  3. Go ahead

In the second loop:

  1. Increment i directly
  2. Go ahead.

So the second loop is more performant for no quality loss. Any other opinions?

codepleb
  • 10,086
  • 14
  • 69
  • 111
  • 1
    The only way to know if the second loop is more performant is to measure it (assuming the assembly code generated si different). With an `int` I doubt it makes a difference. With some iterator types, perhaps. **Edit** I am talking C++ here. – juanchopanza Aug 23 '13 at 11:50
  • 2
    When you say "the variable *will be cached*", do you use any understanding or research of the situation, or are you just speculating? – Kerrek SB Aug 23 '13 at 11:50
  • 6
    I saw a c++ tag, but then it disappeared and I only see java, so I posted the dup for java. – Jesse Good Aug 23 '13 at 11:51
  • Yup, I saw c++ tag also. – Nemanja Boric Aug 23 '13 at 11:51
  • Nano-optimizations like this usually don't make a measurable difference. I doubt that this will matter, even if you're doing extremely heavy scientific calculations. The rest of your code is far more likely to cause problems. Measure, don't guess. – duffymo Aug 23 '13 at 11:57
  • @Kerrek SB: Hm, how should I answer this? We learned it at school and that's what pre- post-condition is for. Maybe I misunderstood you question. --- I removed the C++ Tag in around 14 secs I think, and this was the reaction. :D You're to fast guys. :) – codepleb Aug 23 '13 at 11:59
  • @duffymo With an additional caveat that the measurement is subject to change with not just another JDK Update, but even with another JVM invocation. If there ever was a blanket advice which actually holds, it is about questions like this. – Marko Topolnik Aug 23 '13 at 11:59
  • @TrudleR It's pre- and post- *increment*. Pre- and post- *conditions* are something completely different. – Marko Topolnik Aug 23 '13 at 12:00
  • @TrudleR: I'm pretty sure that you either a) haven't learned *that* in school, or b) you're misrepresenting what you learned in school, or c) you were taught very poorly. The key here is "the value of an expression", which has very little to do with "will be cached". – Kerrek SB Aug 23 '13 at 12:00
  • @Kerrek SB: Our teacher was a long-standing C++ programmer, but he also knows a lot of java and he told us this in our OOP-lessons. But this doesn't really matter. Yeah of course it's increment. I sometimes have a mess in stuff like this. I think everybody has checked, that english isn't my motherlanguage. Maybe cached is the wrong word, not sure but: normally, the post increment does maybe a commandline of maths with the old value (of "i"), which is cached, while "i" reached already the next position. Do you think, this is incorrect? Because he really told us this. – codepleb Aug 23 '13 at 12:24
  • So, both `++i` and `i++` are *expressions*, and evaluating them produces both a value and a side effect. However, if the value of the expression is never used (something you can determine statically, and quite easily, too), then you only need to produce the side effect and never need to worry about the value. So there's no reason that any half-sane compiler wouldn't generate the same for both versions. – Kerrek SB Aug 23 '13 at 12:27
  • Scott Meyer covered all this in his "Effective C++", but that was a long time ago. Java didn't exist when that book was written. Compilers and optimizers have changed a lot in 20 years. Statistics, branching, and runtime optimization are common now. They have a far more profound effect on execution that this simple case. – duffymo Aug 23 '13 at 12:41

1 Answers1

6

In Java there is no point in thinking at this level. The Java runtime is so far removed from what you literally write in Java source code that this kind of reasoning loses any meaning. Specifically, the JIT compiler will warp your code to unintelligibility at the machine code level.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • So it doesn't matter in which case you write it, the compiler makes it to the thing it belongs? I would teach my students this in the way, post- and pre-condition is ment (if I would be a teacher), because this has some "background knowledge", which can always be interesting. But it's interesting, that it doesn't matter. Thx, for you answer! :) – codepleb Aug 23 '13 at 12:02
  • Java's Just-in-Time compiler does so many more complicated things that this almost doesn't even enter the picture. For example, it may erase your whole *loop* if it realizes it has no side-effects. – Marko Topolnik Aug 23 '13 at 12:07
  • That might be correct, but the programming-logic would more fit, if I do this in "my" way, ad I understand this. Of course, it may doesn't matter, but why shouldn't I write the logic, the compiler would also write? Anyway, good anwser, but I wouldn't change what I do at the moment. :) – codepleb Aug 23 '13 at 12:27
  • Of course, go ahead and write it the way it feels the most comfortable to you. Due to the ubiquity of `i++`, you'll get some raised eyebrows from teammates, but nobody should be making scenes out of it. – Marko Topolnik Aug 23 '13 at 12:29