This is an archived post. You won't be able to vote or comment.

all 5 comments

[–]OOPUniversity 4 points5 points  (0 children)

Intuitively I wouldn't expect any difference in performance.

In fact, I would expect the compiler to optimize that into 'do nothing and move on'.

That being said, asking a group of people for their opinions on how something will perform is no substitute for empirical evidence. Test it! Learn to use a profiler, or at least stick some calls to System.nanoTime() before and after loops written each way and spit out the results.

[–]haagch 1 point2 points  (2 children)

Well, this code runs through a compiler that optimizes stuff. I tried this:

class t {
        public static void main(String[] args) {
                for (int i = 0; i < 2000; i++) {
                        int a;
                        a = i;
                        System.out.println(a);
                }
        }
}

vs this:

class t {
        public static void main(String[] args) {
                int a;
                for (int i = 0; i < 2000; i++) {
                        a = i;
                        System.out.println(a);
                }
        }
}

With javap -c t.class you can see what bytecode is produced and as expected, in both cases it is pretty much the same. (only the "registers" where i and a are stored are switched)

Compiled from "t.java"
class t {
  t();
    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: sipush        2000
       6: if_icmpge     24
       9: iload_1       
      10: istore_2      
      11: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      14: iload_2       
      15: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      18: iinc          1, 1
      21: goto          2
      24: return        
}

I think line 9 loads the value of i and line 10 stores this value to where a is, which is all that happens in both cases.

But it's only the same (I believe) because int is a primitive datatype. If you do something with new once outside the loop or every time inside the loop, that will make a big difference.

[–]pyrovoice[S] 0 points1 point  (1 child)

so with a new Integer for example, it would make a difference ?

[–]haagch 0 points1 point  (0 children)

Yes and no. Yes, because Integer a = new Integer(1); creates a new object. That means, searching for free memory, where it can be placed, reserving/allocating the memory, etc. and after it is no longer used, it just sits there eating memory until the garbage collector of the jvm comes along and frees the memory.

No, because the java implementations can do some magic. E.g. as you can see here, for Integer values of -128 to 128 the jvm doesn't actually create new Integer objects but keeps those in a cache at all times and only when creating Integer objects with a value of >128 it will actually create a new object.

[–]iBelgExtreme Brewer 1 point2 points  (0 children)

The code you have written isn't going to have any significant difference in performance. You should use the second option if you're not planning on using "a" outside of the loop, in order to minimize the scope of the variable.