为什么特定的Guava Stopwatch.elapsed()调用比其他调用晚得多? (发布后的结果)

时间:2019-05-01 21:09:51

标签: java guava

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

我尝试在Windows和Linux(Ubuntu 18.04)中以焦点和线程的身份运行以下代码,结果保持不变-确切的值不同,但是会出现差距。我在JDK 11上使用了IntelliJ IDEA环境。

Main的摘要:

public static void main(String[] args) {

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

    planets[0].run();

}

这是我的课程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

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

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

Duration的内部表示形式是 seconds 的数量加上 nano偏移量,表示持续时间中整整一秒的时间。 Duration.getNano()返回该纳米偏移量,除非您也调用Duration.getSeconds(),否则几乎不应调用它。

您可能要调用的方法是toNanos(),它将整个持续时间转换为十亿分之一秒。

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

实际的问题可能是在第一次调用期间必须进行类加载或额外工作的某种组合,和/或JIT会提高以后调用的性能(尽管我认为循环10次并不一定足以使您满意看到JIT的任何变化)。