【问题标题】:Near empty Java For-Loop acts strange近空Java For-Loop行为奇怪
【发布时间】:2013-08-05 02:57:07
【问题描述】:

此代码按预期打印“平均运行次数:0.99864197”

import java.util.Random;

public class A {
    public static void main(String[] args) {
        int min = -30;
        int max = 1;
        test(min, max);
    }
    static void test(int min, int max){
        int count = 0;
        Random rand = new Random(0);
        for(int j = 0; j < 2097152; j++){
            int number = min + rand.nextInt(max-min+1);
            for(int i = 0; i < number; ++i) {
                System.out.print("");
                count++;
            }
        }
        System.out.println("Average Number of Runs: " + count/65536F);

    }
}

这段代码应该打印相同的确切数字,但它会打印一个随机的负数。

import java.util.Random;

public class A {
    public static void main(String[] args) {
        int min = -30;
        int max = 1;
        test(min, max);
    }
    static void test(int min, int max){
        int count = 0;
        Random rand = new Random(0);
        for(int j = 0; j < 2097152; j++){
            int number = min + rand.nextInt(max-min+1);
            for(int i = 0; i < number; ++i) {
                //System.out.print("");
                count++;
            }
        }
        System.out.println("Average Number of Runs: " + count/65536F);

    }
}

java for 循环中是否发生了一些优化?

注意事项:

  1. 我正在使用 jdk1.6.0_45。
  2. 在正常使用中,新的 Random 会有更好的种子。
  3. min 和 max 应该可以是任意数字。

【问题讨论】:

  • 我似乎记得这是重复的,但我怀疑我很难找到它。我认为这是 1.6 中的 JIT 错误,已在 Java 7 中修复。您可以尝试使用 Java 7 吗?
  • @JonSkeet 我刚刚在 Java 7 中尝试过,效果很好。
  • 在 jre 7u25 上运行代码似乎确实解决了这个问题,所以它似乎是 Java 6 中的一个错误。这很糟糕,因为在我的世界社区中有相当多的人,似乎不知道如何更新,这段代码是我一直在研究的游戏修改的一部分......另外@Jon Skeet 你可以发布一个答案,以便我可以将其标记为已接受?
  • @ZaideChris:会的,虽然我不确定它的价值……
  • 两个代码版本都可以在 java 1.6.0_26 上完美运行。

标签: java debugging loops jvm nested-loops


【解决方案1】:

openjdk 1.7.0_25 fedora-2.3.10.4.fc19-x86_64 上运行良好。 您应该更新您的 Java 版本,或确保您的问题实际上与所述代码有关。

【讨论】:

    【解决方案2】:

    我认为这是在 Java 6 的某些版本中 JIT 处理非常紧凑的循环中的一个错误。它可能bug 6196102 或错误6357124

    更新到 Java 7 应该可以工作,尽管我很欣赏这对您的情况没有多大帮助。您可能会发现在循环中添加“看起来不是无操作,但做了一些您不关心的事情”的方法调用也可以解决问题。例如,您可以将 i 的所有值相加,然后将其打印到某个诊断日志以被忽略。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-03
      • 2012-02-02
      • 2018-06-06
      • 1970-01-01
      • 2019-06-27
      • 1970-01-01
      • 2011-07-28
      相关资源
      最近更新 更多