Declaring/initializing 双(或多)循环内部或外部的变量

Declaring/initializing variables inside or outside of a double (or multiple) loop

根据 similar question 和多次 Google 搜索,在循环外或循环内声明或初始化变量 "might" 在性能方面是相同的。

我正在 运行 进行计算机模拟,我正在尝试尽可能地优化代码,因为它必须 运行 很多次并且它有多个内部循环很多迭代。

我想知道是否值得将所有变量移出循环。我有很多 "theoretically" 不断被重新声明的变量。我说 "theoretically" 是因为我不知道 Java 编译器是否真的优化代码并在比方说方法级别声明所有内容。

基本上,什么会更有效率?代码 A 还是代码 B?

代码A:

private void codeA() {
    double a = 0.0;

    for (int i1 = 0; i < i1_N; i1++ ) {
        // Many other loops
             for (int im = 0; i < im_N; im++ ) {
                 a = 0; // a is used for the first time
                 for (int in = 0; i < in_N; in++ ) {
                     a++; // calculate something with a
                 }
             }
        // close many other loops
    }
}

代码 B:

private void codeA() {
    double a;

    for (int i1 = 0; i < i1_N; i1++ ) {
        // Many other loops
             for (int im = 0; i < im_N; im++ ) {
                 a = 0; // a is used for the first time
                 for (int in = 0; i < in_N; in++ ) {
                     a++; // calculate something with a
                 }
             }
        // close many other loops
    }
}

代码 C:

private void codeC() {

    for (int i1 = 0; i < i1_N; i1++ ) {
        // Many other loops
             for (int im = 0; i < im_N; im++ ) {
                 double a = 0; // a is used for the first time
                 for (int in = 0; i < in_N; in++ ) {
                     a++; // calculate something with a
                 }
             }
        // close many other loops
    }
}

我只是在这个例子中使用了变量a,但是计算机模拟使用了更多。我的大部分变量都是原始变量(int、double、float)。为了提高性能而在循环外声明原语是否有意义?

javac不会优化。在所有 3 个案例中生成的字节码 is different。 (javac Test.java 编译并且 javap -c Test.class 显示字节码)

Java 虚拟机可能会优化。

JMH 基准显示明显的赢家:

Benchmark           Mode  Cnt    Score    Error  Units
MyBenchmark.testA  thrpt   20  423.437 ±  6.745  ops/s
MyBenchmark.testB  thrpt   20  337.728 ± 56.363  ops/s
MyBenchmark.testC  thrpt   20  351.419 ± 70.290  ops/s

单位是每秒的操作次数,越多越好。 Benchmark source code。使用了 OpenJDK IcedTea 2.5.4 Java 虚拟机。

所以,在外部声明和初始化变量应该是最有效的。