用Java调用全局变量:没有开销?

时间:2016-05-27 18:34:24

标签: java performance

我发现了这个StackOverflow帖子:

Why does Python code run faster in a function?

该帖子的问题的简短答案是"存储局部变量比全局变量更快#34;。因此,有时将循环放在方法中是值得的。

我试图检查这个陈述是否适用于Java,并写了这个样本:

public class Main {
    // Global <<iter>> variable:
    public static long ITER = (long) Math.pow(2, 35);

    public static void main(String[] args) {
        // call method from some loop:
        long startTime1 = System.currentTimeMillis();
        // meat 1:
        for (long i = 0; i < Main.ITER; i++){
            long p = Main.ITER;
        }
        // print results:
        long stopTime1 = System.currentTimeMillis();
        long elapsedTime1 = stopTime1 - startTime1;
        System.out.println("Simple loop takes " 
            + elapsedTime1 + " ms to finish.");

        // put method in the loop:
        long startTime2 = System.currentTimeMillis();
        // meat 2:
        myMethod1(Main.ITER);
        // print results:
        long stopTime2 = System.currentTimeMillis();
        long elapsedTime2 = stopTime2 - startTime2;
        System.out.println("Same loop in the method takes " 
            + elapsedTime2 + " ms to finish.");
    }

    public static void myMethod1(long iter) {
        for (long i = 0; i < iter; i++){
            long p = iter;
        }
    }
}

我希望代码在Main.ITER中多次调用meat 1,在meat 2部分只调用一次,然后比较两者花费的毫秒数。我跑了好几次,结果总是接近:

Simple loop takes 9199 ms to finish.
Same loop in the method takes 9123 ms to finish.

我的JVM(Eclipse安装详细信息的输出):

java.vm.info=mixed mode
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
java.vm.specification.name=Java Virtual Machine Specification
java.vm.specification.vendor=Oracle Corporation
java.vm.specification.version=1.7
java.vm.vendor=Oracle Corporation
java.vm.version=24.80-b11

这是来自meat 1部分的循环的字节码:

    9 getstatic 20;           /* test6.Main.ITER */
    14 lload_3;               /* i */
    15 lconst_1;
    16 ladd;
    17 lstore_3;              /* i */
    18 lload_3;               /* i */
    19 getstatic 20;          /* test6.Main.ITER */
    22 lcmp;
    23 iflt -14;

以下是meat 2部分中使用的方法中循环的字节码:

    5 lload_0;                /* iter */
    6 lstore 4;
    /* L32 */
    8 lload_2;                /* i */
    9 lconst_1;
    10 ladd;
    11 lstore_2;              /* i */
    12 lload_2;               /* i */
    13 lload_0;               /* iter <- No Main.ITER here ... */
    14 lcmp;
    15 iflt -10;

我不是Java字节码的专家,但似乎myMethod1()没有调用全局变量Main.ITER

问题:

  • 这种测试的Java实现是否正确?我可能会想念一些 关于JVM如何工作和优化此代码的一般概念。
  • 我的结果是否意味着在Java中调用全局变量而不是本地变量没有开销?例如。如果我用某种方法循环,​​它不会改变游戏吗?

提前谢谢。

0 个答案:

没有答案