Difference between declaring variables before or in loop?

前端 未结 25 2076
长发绾君心
长发绾君心 2020-11-22 02:37

I have always wondered if, in general, declaring a throw-away variable before a loop, as opposed to repeatedly inside the loop, makes any (performance) difference? A (q

25条回答
  •  一向
    一向 (楼主)
    2020-11-22 03:28

    I had this very same question for a long time. So I tested an even simpler piece of code.

    Conclusion: For such cases there is NO performance difference.

    Outside loop case

    int intermediateResult;
    for(int i=0; i < 1000; i++){
        intermediateResult = i+2;
        System.out.println(intermediateResult);
    }
    

    Inside loop case

    for(int i=0; i < 1000; i++){
        int intermediateResult = i+2;
        System.out.println(intermediateResult);
    }
    

    I checked the compiled file on IntelliJ's decompiler and for both cases, I got the same Test.class

    for(int i = 0; i < 1000; ++i) {
        int intermediateResult = i + 2;
        System.out.println(intermediateResult);
    }
    

    I also disassembled code for both the case using the method given in this answer. I'll show only the parts relevant to the answer

    Outside loop case

    Code:
      stack=2, locals=3, args_size=1
         0: iconst_0
         1: istore_2
         2: iload_2
         3: sipush        1000
         6: if_icmpge     26
         9: iload_2
        10: iconst_2
        11: iadd
        12: istore_1
        13: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        16: iload_1
        17: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        20: iinc          2, 1
        23: goto          2
        26: return
    LocalVariableTable:
            Start  Length  Slot  Name   Signature
               13      13     1 intermediateResult   I
                2      24     2     i   I
                0      27     0  args   [Ljava/lang/String;
    

    Inside loop case

    Code:
          stack=2, locals=3, args_size=1
             0: iconst_0
             1: istore_1
             2: iload_1
             3: sipush        1000
             6: if_icmpge     26
             9: iload_1
            10: iconst_2
            11: iadd
            12: istore_2
            13: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
            16: iload_2
            17: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
            20: iinc          1, 1
            23: goto          2
            26: return
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
               13       7     2 intermediateResult   I
                2      24     1     i   I
                0      27     0  args   [Ljava/lang/String;
    

    If you pay close attention, only the Slot assigned to i and intermediateResult in LocalVariableTable is swapped as a product of their order of appearance. The same difference in slot is reflected in other lines of code.

    • No extra operation is being performed
    • intermediateResult is still a local variable in both cases, so there is no difference access time.

    BONUS

    Compilers do a ton of optimization, take a look at what happens in this case.

    Zero work case

    for(int i=0; i < 1000; i++){
        int intermediateResult = i;
        System.out.println(intermediateResult);
    }
    

    Zero work decompiled

    for(int i = 0; i < 1000; ++i) {
        System.out.println(i);
    }
    

提交回复
热议问题