精度与 精确
我想知道的是在更新对象在游戏中的位置时应该使用System.currentTimeMillis()还是System.nanoTime() ? 他们的运动变化与自上次通话以来经过的时间成正比,我想尽可能地精确。
我了解到,不同的操作系统之间存在一些严重的时间分辨率问题(即Mac / Linux的分辨率几乎为1毫秒,而Windows的分辨率为50毫秒?)。 我主要是在Windows上运行我的应用,而50ms的分辨率似乎非常不准确。
是否有比我列出的两个更好的选择?
有什么建议/意见吗?
#1楼
这里的一件事是nanoTime方法的不一致。对于相同的输入,它不会给出非常一致的值。currentTimeMillis在性能和一致性方面要好得多,并且尽管不如nanoTime精确,但误差范围较小,因此其值的准确性更高。 因此,我建议您使用currentTimeMillis
#2楼
就像其他人所说的,currentTimeMillis是时钟时间,由于夏时制,用户更改时间设置,leap秒和互联网时间同步而改变。 如果您的应用依赖于单调增加的经过时间值,则您可能更喜欢nanoTime。
您可能会认为玩家不会在游戏过程中摆弄时间设置,也许您是对的。 但是,请不要低估由于Internet时间同步或远程桌面用户造成的中断。 nanoTime API不受这种破坏的影响。
如果要使用时钟时间,但要避免由于Internet时间同步而导致中断,则可以考虑使用NTP客户端(例如Meinberg),该客户端可以将时钟速率“调整”为零,而不仅仅是定期重置时钟。
我是根据个人经验讲的。 在我开发的天气应用程序中,我得到了随机出现的风速峰值。 我花了一段时间才意识到典型的PC上的时钟时间行为干扰了我的时基。 当我开始使用nanoTime时,我所有的问题都消失了。 一致性(单调性)对我的应用程序比原始精度或绝对精度更重要。
#3楼
如果你只是在寻找的经过时间非常精确的测量,使用System.nanoTime()
System.currentTimeMillis()
将为您提供自该纪元以来最精确的经过时间(以毫秒为单位System.nanoTime()
,但是System.nanoTime()
为您提供相对于某个任意点的纳秒级精确时间。
从Java文档中:
public static long nanoTime()
返回最精确的可用系统计时器的当前值(以纳秒为单位)。
此方法只能用于测量经过时间,并且与系统或挂钟时间的任何其他概念无关。 返回的值表示自某个固定但任意的原始时间以来的纳秒(也许是将来的时间,因此值可能为负)。 此方法提供纳秒精度,但不一定提供纳秒精度。 不能保证值更改的频率。 由于数值溢出,跨越大约292年(2 63纳秒)的连续呼叫中的差异将无法准确计算经过的时间。
例如,要测量某些代码执行所需的时间:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
另请参阅: JavaDoc System.nanoTime()和JavaDoc System.currentTimeMillis()了解更多信息。
#4楼
较早的JVM不支持System.nanoTime()
。 如果这是一个问题,请坚持使用currentTimeMillis
关于准确性,您几乎是正确的。 在某些Windows计算机上, currentTimeMillis()
的分辨率约为10毫秒(而非50毫秒)。 我不确定为什么,但是某些Windows机器和Linux机器一样准确。
我过去使用GAGETimer取得了一定的成功。
#5楼
是的,如果需要这种精度,请使用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)); }
}
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3168063