为什么特定的 Guava Stopwatch.elapsed() 调用比其他的晚得多? (在post中输出)

Why is a particular Guava Stopwatch.elapsed() call much later than others? (output in post)

我正在做一个小型游戏项目,想要跟踪时间以便处理物理。在浏览了不同的方法之后,起初我决定使用 Java 的 InstantDuration classes,现在切换到 Guava 的 Stopwatch 实现,然而,在我的代码片段中,这两种方法在 runtime.elapsed()second 调用处都有很大差距。从长远来看,这似乎不是什么大问题 运行,但为什么会这样呢?

我在 Windows 和 Linux (Ubuntu 18.04) 中尝试 运行 将下面的代码作为焦点和线程,结果保持不变 - 确切的值不同,但会出现差距。我正在使用 JDK 11.

的 IntelliJ IDEA 环境

主要片段:

public static void main(String[] args) {

    MassObject[] planets = {
        new Spaceship(10, 0, 6378000)
    };

    planets[0].run();

}

这是我的一部分 class MassObject extends Thread:

public void run() {
    // I am using StringBuilder to eliminate flushing delays.
    StringBuilder output = new StringBuilder();
    Stopwatch runtime = Stopwatch.createStarted();

    // massObjectList = static List<MassObject>;
    for (MassObject b : massObjectList) {
        if(b!=this) calculateGravity(this, b);
    }
    for (int i = 0; i < 10; i++) {
        output.append(runtime.elapsed().getNano()).append("\n");
    }
    System.out.println(output);
}

标准输出:

30700
1807000
1808900
1811600
1812400
1813300
1830200
1833200
1834500
1835500

感谢您的帮助。

您在 elapsed() 返回的 Duration 上调用 Duration.getNano(),这不是您想要的。

Duration 的内部表示是 加上一个 纳米偏移量 整整一秒都在持续时间里。 Duration.getNano() returns 纳米偏移量,除非您同时调用 Duration.getSeconds().

,否则几乎不应该调用

您可能想要调用的方法是 toNanos(),它将整个持续时间转换为纳秒数。

编辑: 在这种情况下,这并不能解释你所看到的,因为它确实显示正在打印的纳米偏移可能都在同一秒内,但它是仍然是您不应该使用 getNano().

的情况

实际问题可能是第一次调用期间必须发生的类加载或额外工作的某种组合,and/or JIT 提高了未来调用的性能(尽管我认为循环 10 次不一定足够您会看到 JIT 带来的很多变化)。