문제

정확도 대.정도

내가 알고 싶은 것은 사용해야하는지 여부입니다. 시스템.현재TimeMillis() 또는 시스템.나노타임() 내 게임에서 내 개체의 위치를 ​​업데이트할 때?움직임의 변화는 마지막 호출 이후 경과된 시간에 정비례하므로 최대한 정확하고 싶습니다.

나는 서로 다른 운영 체제 간에 몇 가지 심각한 시간 해상도 문제가 있다는 것을 읽었습니다(즉, Mac/Linux의 해상도는 거의 1ms이고 Windows의 해상도는 50ms입니다.).저는 주로 Windows에서 앱을 실행하고 있는데 50ms 해상도가 꽤 부정확해 보입니다.

내가 나열한 두 가지보다 더 나은 옵션이 있습니까?

제안/의견이 있으신가요?

도움이 되었습니까?

해결책

매우 정확한 측정을 원하신다면 경과 시간, 사용 System.nanoTime(). System.currentTimeMillis() 에포크 이후 가장 정확한 경과 시간을 밀리초 단위로 제공하지만 System.nanoTime() 임의의 지점을 기준으로 나노초 단위의 정확한 시간을 제공합니다.

Java 문서에서:

public static long nanoTime()

사용 가능한 가장 정확한 시스템 타이머의 현재 값을 나노초 단위로 반환합니다.

이 방법은 경과 시간을 측정하는 데만 사용될 수 있으며 시스템 또는 벽 클로크 시간의 다른 개념과 관련이 없습니다.반환되는 값은 다음과 같습니다 는 나노초를 나타내므로 일부 고정되어 있지만 임의의 시간 (아마도 따라서 가치는 다음과 같을 수 있습니다 음수).이 방법은 다음을 제공합니다 나노초 단위의 정밀도를 제공하지만 반드시 나노초 정확도일 필요는 없습니다.아니요 어떻게 보장되는지 값이 자주 변경됩니다.차이점 더 큰 범위의 연속 통화에서 약 292년(263 나노초)는 정확하게 숫자로 인한 경과 시간 계산 오버플로.

예를 들어 일부 코드를 실행하는 데 걸리는 시간을 측정하려면 다음을 수행하세요.

long startTime = System.nanoTime();    
// ... the code being measured ...    
long estimatedTime = System.nanoTime() - startTime;

또한보십시오: JavaDoc System.nanoTime() 그리고 JavaDoc System.currentTimeMillis() 더 많은 정보를 위해서.

다른 팁

이 내용을 다른 사람이 언급한 적이 없기 때문에…

결과를 비교하는 것은 안전하지 않습니다. System.nanoTime() 서로 다른 스레드 간의 호출.스레드의 이벤트가 예측 가능한 순서로 발생하더라도 나노초 단위의 차이는 양수일 수도 있고 음수일 수도 있습니다.

System.currentTimeMillis() 스레드 간에 사용하기에 안전합니다.

업데이트 기준 아르카디:나는 더 정확한 행동을 관찰했습니다 System.currentTimeMillis() Oracle Java 8의 Windows 7에서.시간은 1밀리초 정밀도로 반환되었습니다.OpenJDK의 소스 코드는 변경되지 않았으므로 더 나은 동작의 원인이 무엇인지 모르겠습니다.


Sun의 David Holmes는 몇 년 전에 Java 타이밍 API(특히 System.currentTimeMillis() 그리고 System.nanoTime()), 어떤 것을 사용하고 싶을 때, 내부적으로 어떻게 작동하는지.

핫스팟 VM 내부:시계, 타이머 및 이벤트 예약 - 1부 - Windows

시간 제한 대기 매개변수가 있는 API에 대해 Windows에서 Java가 사용하는 타이머의 매우 흥미로운 측면 중 하나는 타이머의 확인이 수행된 다른 API 호출에 따라 변경될 수 있다는 것입니다. 시스템 전체에서(특정 프로세스뿐만 아니라) .그는 다음을 사용하는 예를 보여줍니다. Thread.sleep() 이 해상도 변경이 발생합니다.

System.nanoTime() 이전 JVM에서는 지원되지 않습니다.그게 걱정된다면 계속 유지하세요. currentTimeMillis

정확성에 관해서는 거의 정확합니다.일부 Windows 시스템에서는 currentTimeMillis() 해상도는 약 10ms(50ms 아님)입니다.이유는 잘 모르겠지만 일부 Windows 시스템은 Linux 시스템만큼 정확합니다.

나는 사용했다 GAGE타이머 과거에는 적당한 성공을 거두었습니다.

다른 사람들이 말했듯이 currentTimeMillis는 일광 절약 시간제, 사용자의 시간 설정 변경, 윤초 및 인터넷 시간 동기화로 인해 변경되는 시계 시간입니다.앱이 단조롭게 증가하는 경과 시간 값에 의존하는 경우 대신 nanoTime을 선호할 수 있습니다.

플레이어가 게임 플레이 중에 시간 설정을 조작하지 않을 것이라고 생각할 수도 있지만 아마도 당신의 말이 옳을 수도 있습니다.그러나 인터넷 시간 동기화나 원격 데스크톱 사용자로 인한 중단을 과소평가하지 마십시오.nanoTime API는 이러한 종류의 중단에 영향을 받지 않습니다.

시계 시간을 사용하고 싶지만 인터넷 시간 동기화로 인한 불연속성을 피하려면 시계를 주기적으로 재설정하는 대신 시계 속도를 0으로 "조정"하는 Meinberg와 같은 NTP 클라이언트를 고려할 수 있습니다.

나는 개인적인 경험에서 말한다.제가 개발한 날씨 애플리케이션에서 풍속 스파이크가 무작위로 발생했습니다.일반적인 PC의 시계 시간 동작으로 인해 내 타임베이스가 중단되고 있다는 사실을 깨닫는 데는 시간이 좀 걸렸습니다.nanoTime을 사용하기 시작했을 때 모든 문제가 사라졌습니다.내 응용 프로그램에서는 원시 정밀도나 절대 정확도보다 일관성(단조성)이 더 중요했습니다.

예, 그러한 정밀도가 필요한 경우에는 다음을 사용하십시오. 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)); }
    }

나는 좋은 경험을 했습니다. 나노타임.JNI 라이브러리를 사용하여 벽시계 시간을 2개의 긴 시간(에포크 이후의 초 및 해당 초 내의 나노초)으로 제공합니다.Windows 및 Linux용으로 사전 컴파일된 JNI 부분과 함께 사용할 수 있습니다.

게임 그래픽 및 원활한 위치 업데이트를 위해 다음을 사용하세요. System.nanoTime() 오히려 System.currentTimeMillis().게임에서 currentTimeMillis()를 nanoTime()으로 전환했는데 동작의 부드러움이 시각적으로 크게 향상되었습니다.

1밀리초는 이미 정확해야 하는 것처럼 보이지만 시각적으로는 그렇지 않습니다.요인 nanoTime() 개선할 수 있는 사항은 다음과 같습니다.

  • 벽시계 해상도 이하의 정확한 픽셀 위치 지정
  • 원하는 경우 픽셀 간 앤티앨리어싱 기능
  • Windows 벽시계 부정확성
  • 시계 지터(벽시계가 실제로 앞으로 움직일 때의 불일치)

다른 답변에서 알 수 있듯이 nanoTime은 반복적으로 호출하면 성능 비용이 발생합니다. 프레임당 한 번만 호출하고 동일한 값을 사용하여 전체 프레임을 계산하는 것이 가장 좋습니다.

System.currentTimeMillis() 이 방법은 시스템의 실시간 시계 변경에 민감하기 때문에 경과 시간에 안전하지 않습니다.당신은 사용해야합니다 System.nanoTime.Java 시스템 도움말을 참조하십시오.

nanoTime 방법 정보:

..이 방법은 나노초 단위의 정밀도를 제공하지만, 반드시 나노초 해상도(즉, 값이 얼마나 자주 변경되는지) - 아니요 해상도가 최소한 다음과 같다는 것을 제외하고는 보장하지 않습니다 currentTimeMillis()...

당신이 사용하는 경우 System.currentTimeMillis() 경과 시간은 음수가 될 수 있습니다. (뒤로 <-- 미래로)

여기서 한 가지는 nanoTime 방법의 불일치입니다. 동일한 입력에 대해 매우 일관된 값을 제공하지 않습니다. currentTimeMillis는 성능과 일관성 측면에서 훨씬 더 우수하며, nanoTime만큼 정확하지는 않지만 오류 마진이 더 낮습니다. , 따라서 그 값이 더 정확해집니다.그러므로 currentTimeMillis를 사용하는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top