2

I think the question should be self explanatory, and the language I'm thinking about right now is Java, but it probably applies across all languages.

That being said, basically what I'm talking about is whether this:

// Initialize first
int i = 0;

for (i = 0; i < x; i++) {
    // do some stuff
}

for (i = 0; i < x; i++) {
    // do some more stuff
}

for (i = 0; i < x; i++)  {
    // do other stuff
}

Is better than this:

// Initializing i in the for loop

for(int i = 0; i < x; i++) {
    // do some stuff
}

for(int i = 0; i < x; i++) {
    // do some more stuff
}

for(int i = 0; i < x; i++) {
    // do other stuff
}

This is a performance question, and I'm talking about initializing once /per/ scope resolution.

Maroun
  • 94,125
  • 30
  • 188
  • 241
bigcodeszzer
  • 916
  • 1
  • 8
  • 27
  • No performance difference. – keshlam Mar 03 '16 at 06:37
  • Today's Java optimezers are smart enough to generate *equal code* in both cases; however, the second option i.e. `for(int i = 0; i < x; i++)` is more *readable* and thus preferable – Dmitry Bychenko Mar 03 '16 at 06:38
  • @DmitryBychenko That's what I was thinking also. – bigcodeszzer Mar 03 '16 at 06:39
  • You can have a little gain if you *reverse* the loop (if it's possible): `for(int i = x - 1; i >= 0; --i)` since comparison with zero (`JZ`, `JNZ` assembler commands) are faster than comparison with a constant – Dmitry Bychenko Mar 03 '16 at 06:41
  • 1
    well this might not be related to your specific question, But ++i is speeder than i++ . because i++ takes more processing curves than ++i. isn't it? – Damith Mar 03 '16 at 06:42
  • As @hackmith said. For better performance use pre-increment if possible. See http://stackoverflow.com/a/24904/1879699. – Andreas Mar 03 '16 at 06:58
  • Both of these tips are interesting. – bigcodeszzer Mar 03 '16 at 07:00
  • @hackmith: Only for custom types, no? (But it doesn't hurt to make using the pre-increment a habit, of course.) – M Oehm Mar 03 '16 at 07:06

4 Answers4

2

I performed a performance test with x=10 to evaluate the performance difference between the in-loop declaration method and the out-of-loop declaration method.

Details: I ran the code 300x with in-loop first and then 300x with out-of-loop first. Each run, I recorded the total runtime in nanoseconds to execute each method 10,000 times. So, I recorded a total of 1200 observations (600 per method). To measure steady-state performance (vice startup performance), I removed the 20 observations from each data set that had the longest duration. (The mean runtime for the 20 startup observations was an order of magnitude larger than the mean runtime for all the other observations.)

Results: A single-factor ANOVA indicates that the in-loop declaration is faster than the out-of-loop declaration (p-value=8.12584E-07). The mean runtimes were 158635.4931 nanoseconds for in-loop and 166943.7397 nanoseconds for out-of-loop. From a practical standpoint, we're talking about a difference of ~0.01ms per 10,000 iterations.

Conclusion: Just use the in-loop declaration. @FallAndLearn also points out that the in-loop declaration is easier to maintain because the local variable i is declared with the smallest scope possible .

Austin
  • 8,018
  • 2
  • 31
  • 37
0

The scope of local variables should always be the smallest possible.

Hence if int i is not used outside the loop then second way is always better. More readable too.

Performance wise they are both same. From a maintenance perspective, second option is better.

Also, the answers to this question will depend on your requirement. If your code has other data dependent on i or have only three for loops statement.

FallAndLearn
  • 4,035
  • 1
  • 18
  • 24
0

You first piece of code is better than second one because int is a value type and its value is stored in stack once you initialize it , later on you just assign that type a value again and again . On the other hand (second piece of code )you are initializing i three times i.e. creating stack entries three times . So the first piece of code is better than the second one , performance wise .

  • I was thinking that too, but it everybody is saying it doesn't make a difference. Which is just making me confused. – bigcodeszzer Mar 03 '16 at 06:58
  • 1
    Do you have data to back this up? Surely the compiler can see that `i` is used independently and use the same stack space for each instance. I doubt that the used stack space grows and shrinks between the loops. – M Oehm Mar 03 '16 at 07:00
0

Let's check out the disassembled code for the following snippet:

public class Test {
    public static void main(String[] args) {
        int i = 0;
        for(i = 0; i < 3; i++){
            //do some stuff
        }
    }
}

public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1    // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_0
       3: istore_1
       4: iload_1
       5: iconst_3
       6: if_icmpge     15
       9: iinc          1, 1
      12: goto          4
      15: return
}

Now let's generate another one for the initialization of the control variable inside the loop:

public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1    // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iload_1
       3: iconst_3
       4: if_icmpge     13
       7: iinc          1, 1
      10: goto          2
      13: return
}

They're not the same, I'm not a byte-code expert but I can tell that the second one has less overhead. The first one pushes int constant twice (the two iconst_<i> instructions), and has two istore_<n> instructions, compared to one instruction in the second code.

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • It's probably that the JVM is smart enough to figure it out in the one case, no? I've heard idiomatic code is usually faster once its compiled. Do you get the same result in C or C++? – bigcodeszzer Mar 03 '16 at 08:02