准确Vs.精确
我想知道的是,我是否应该使用系统。currenttimemillis()或系统。nanotime()时更新我的对象的位置在我的游戏?它们移动的变化与上次通话后经过的时间成正比,我希望尽可能精确。
我读到过不同操作系统之间有一些严重的时间分辨率问题(即Mac / Linux的分辨率几乎是1毫秒,而Windows的分辨率是50毫秒??)我主要在windows上运行我的应用程序,50ms的分辨率似乎非常不准确。
还有比我列出的两个更好的选择吗?
有什么建议/意见吗?
准确Vs.精确
我想知道的是,我是否应该使用系统。currenttimemillis()或系统。nanotime()时更新我的对象的位置在我的游戏?它们移动的变化与上次通话后经过的时间成正比,我希望尽可能精确。
我读到过不同操作系统之间有一些严重的时间分辨率问题(即Mac / Linux的分辨率几乎是1毫秒,而Windows的分辨率是50毫秒??)我主要在windows上运行我的应用程序,50ms的分辨率似乎非常不准确。
还有比我列出的两个更好的选择吗?
有什么建议/意见吗?
当前回答
这里的一个问题是nanoTime方法的不一致性。对于相同的输入,它不会给出非常一致的值。currentTimeMillis在性能和一致性方面做得更好,而且,尽管没有nanoTime那么精确,但它的误差范围更低,因此它的值更准确。因此,我建议您使用currentTimeMillis
其他回答
既然没人提过这一点……
在不同的JVM之间比较System.nanoTime()调用的结果是不安全的,每个JVM可能有一个独立的“起始”时间。
system . currenttimemillis()将在jvm之间返回(近似)相同的值,因为它与系统墙壁时钟时间绑定。
如果你想计算两个事件之间经过的时间,就像秒表一样,使用nanoTime();系统时钟的改变使得currentTimeMillis()在这个用例中不正确。
我对纳米时间有丰富的经验。它使用JNI库提供了两个长度的挂钟时间(从纪元开始的秒数和在这一秒内的纳秒)。在Windows和Linux上都可以使用预编译的JNI部分。
是的,如果需要这样的精度,请使用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)); }
}
正如其他人所说,currentTimeMillis是时钟时间,由于夏令时而改变(不是:夏令时和时区与currentTimeMillis无关,其余为真),用户更改时间设置,闰秒和互联网时间同步。如果您的应用程序依赖于单调增加运行时间值,您可能更喜欢nanoTime。
你可能认为玩家不会在游戏过程中摆弄时间设置,也许你是对的。但不要低估互联网时间同步或远程桌面用户带来的破坏。nanoTime API不会受到这种中断的影响。
如果你想使用时钟时间,但避免由于互联网时间同步造成的间断,你可以考虑一个NTP客户端,如Meinberg,它“调整”时钟速率为零,而不是定期重置时钟。
这是我的亲身经历。在我开发的一个天气应用程序中,我得到了随机出现的风速峰值。我花了一段时间才意识到,我的时间库被一台典型PC上的时钟时间行为打乱了。当我开始使用nanoTime时,我所有的问题都消失了。对于我的应用程序来说,一致性(单调性)比原始精度或绝对精度更重要。
system. currenttimemillis()对于运行时间来说是不安全的,因为这个方法对系统的实时时钟变化很敏感。 您应该使用System.nanoTime。 请参阅Java系统帮助:
关于nanoTime方法:
. .这种方法提供纳秒精度,但不一定 纳秒分辨率(即值变化的频率)—不 除了保证分辨率至少和 currentTimeMillis()..
如果你使用System.currentTimeMillis(),你的运行时间可以是负数(返回<-到未来)