准确Vs.精确

我想知道的是,我是否应该使用系统。currenttimemillis()或系统。nanotime()时更新我的对象的位置在我的游戏?它们移动的变化与上次通话后经过的时间成正比,我希望尽可能精确。

我读到过不同操作系统之间有一些严重的时间分辨率问题(即Mac / Linux的分辨率几乎是1毫秒,而Windows的分辨率是50毫秒??)我主要在windows上运行我的应用程序,50ms的分辨率似乎非常不准确。

还有比我列出的两个更好的选择吗?

有什么建议/意见吗?


当前回答

我对纳米时间有丰富的经验。它使用JNI库提供了两个长度的挂钟时间(从纪元开始的秒数和在这一秒内的纳秒)。在Windows和Linux上都可以使用预编译的JNI部分。

其他回答

既然没人提过这一点……

在不同的JVM之间比较System.nanoTime()调用的结果是不安全的,每个JVM可能有一个独立的“起始”时间。

system . currenttimemillis()将在jvm之间返回(近似)相同的值,因为它与系统墙壁时钟时间绑定。

如果你想计算两个事件之间经过的时间,就像秒表一样,使用nanoTime();系统时钟的改变使得currentTimeMillis()在这个用例中不正确。

是的,如果需要这样的精度,请使用System.nanoTime(),但请注意,您需要Java 5+ JVM。

在我的XP系统上,我看到系统时间报告为至少100微秒278纳秒,使用以下代码:

private void test() {
    System.out.println("currentTimeMillis: "+System.currentTimeMillis());
    System.out.println("nanoTime         : "+System.nanoTime());
    System.out.println();

    testNano(false);                                                            // to sync with currentTimeMillis() timer tick
    for(int xa=0; xa<10; xa++) {
        testNano(true);
        }
    }

private void testNano(boolean shw) {
    long strMS=System.currentTimeMillis();
    long strNS=System.nanoTime();
    long curMS;
    while((curMS=System.currentTimeMillis()) == strMS) {
        if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)); }
        }
    if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)+", Milli: "+(curMS-strMS)); }
    }

旧的jvm中不支持System.nanoTime()。如果这是一个问题,请坚持使用currentTimeMillis

关于准确性,你几乎是正确的。在一些Windows机器上,currentTimeMillis()的分辨率约为10ms(而不是50ms)。我不知道为什么,但是一些Windows机器和Linux机器一样准确。

我过去使用过GAGETimer,取得了一定的成功。

对于游戏图像和平滑的位置更新,使用System.nanoTime()而不是System.currentTimeMillis()。我在游戏中从currentTimeMillis()切换到nanoTime(),在运动的平滑度上有了很大的视觉改善。

虽然1毫秒看起来已经很精确了,但从视觉上看并非如此。nanoTime()可以改进的因素包括:

精确的像素定位低于时钟分辨率 如果你想要,像素之间的抗别名能力 窗户挂钟不准 时钟抖动(当挂钟实际滴答前进时不一致)

正如其他答案所表明的那样,如果重复调用nanoTime,确实会有性能损失——最好每帧只调用一次,并使用相同的值来计算整个帧。

我对纳米时间有丰富的经验。它使用JNI库提供了两个长度的挂钟时间(从纪元开始的秒数和在这一秒内的纳秒)。在Windows和Linux上都可以使用预编译的JNI部分。