10

次の Java コードを検討してください。

public int main() {
    int i = 1111;

    for (; rules(i) != true && i < Integer.MAX_VALUE; i++) {
        //LOG.debug("Testing i: " + i);
    }

    System.out.println("The mystery number is: " + i);

    return i;
}

protected boolean rules(int nb) {
    //...
}

truefor ループの継続評価がの場合でも、本体が空になるとループの実行が停止することがわかりました。

の最終結果mainは間違っています (i約 98% の確率で 16698 であり、少し高い/低い場合もあります)。

ループ本体から LOG ステートメントのコメントを外すと、ループ継続の評価が になるまでループが実行され続けますfalse

私が使用している JVM は MacOS X VM 1.6.0 です。

  • ある種のランタイム最適化を行っていますか?
  • この実行時の最適化はバグと見なすことができますか?
  • それとも、Java 仕様のどこかで、継続評価のために機能操作を実行してはならないと言われていますか?

ps: 完全なコード ソースとその単体テストは、https ://gist.github.com/dirtyhenry/5804130 から入手できます。

アップデート:

  • 私はjunitのみを介してコードを実行しました。junit はこの動作に責任がありますか?

更新 2:

java -version

戻り値:

java version "1.6.0_51"
Java(TM) SE Runtime Environment (build 1.6.0_51-b11-456-11M4508)
Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01-456, mixed mode)
4

7 に答える 7

3

私はここで同様の問題を抱えていました:ほとんど空の Java For-Loop の動作がおかしい JVM 1.7 を使用するか、while ループを使用してみてください:

public int main() {
    int i = 1111;

    while(i < Integer.MAX_VALUE){
        if (!rules(i)) {
            break;
        }
        i++
    }

    System.out.println("The mystery number is: " + i);

    return i;
}
于 2013-08-15T10:19:53.457 に答える
0

何もしないループと条件は、JIT コンパイラーによって最適化される可能性があります。これは間違いなく起こっていることです。

于 2013-06-18T15:51:20.657 に答える
0

もう 1 つのオプションは、ブロック内でルール テストを実行することです。JIT コンパイラーは、ループが空であるため、ループをスローしている可能性があります。次のようなことを試してください:

public int main() {
    int i = 1111;

    for (; i < Integer.MAX_VALUE; i++) {
        boolean completed = !rules(i);
        if (completed) {
            break;
        }
    }

    System.out.println("The mystery number is: " + i);

    return i;
}
于 2013-07-23T12:28:04.060 に答える
0

ログ ステートメントを他の (コメント化されていない) 有効なステートメントに置き換えてみてください。その場合、ループも期待どおりに実行されます。その間違いなく JVM コードの最適化戦略です。JVM が理由もなくループを循環する理由はないと思います。

于 2013-06-18T12:05:35.373 に答える