System.nanoTime ()이 System.currentTimeMillis ()보다 성능이 훨씬 느린 이유는 무엇입니까?
오늘 저는 System.nanoTime()
및의 속도 성능을 테스트하기 위해 간단한 벤치 마크를 수행했습니다 System.currentTimeMillis()
.
long startTime = System.nanoTime();
for(int i = 0; i < 1000000; i++) {
long test = System.nanoTime();
}
long endTime = System.nanoTime();
System.out.println("Total time: "+(endTime-startTime));
결과는 다음과 같습니다.
System.currentTimeMillis(): average of 12.7836022 / function call
System.nanoTime(): average of 34.6395674 / function call
달리기 속도의 차이가 왜 그렇게 큰가요?
벤치 마크 시스템 :
Java 1.7.0_25
Windows 8 64-bit
CPU: AMD FX-6100
에서 이 오라클 블로그 :
System.currentTimeMillis()
기본적으로 Windows에서 유지 관리하는 저해상도 시간 값을 읽는 GetSystemTimeAsFileTime 메서드를 사용하여 구현됩니다. 이 전역 변수를 읽는 것은 당연히 매우 빠릅니다.보고 된 정보에 따르면 약 6주기입니다.
System.nanoTime()
를 사용하여 구현됩니다QueryPerformanceCounter/ QueryPerformanceFrequency API
(사용 가능한 경우currentTimeMillis*10^6)
.를 반환합니다 .QueryPerformanceCounter(QPC)
실행중인 하드웨어에 따라 다른 방식으로 구현됩니다. 일반적으로 PIT (프로그래밍 가능 간격 타이머) 또는 ACPI PMT (전원 관리 타이머)를 사용합니다. 또는 CPU 레벨 타임 스탬프 카운터 (TSC)입니다. PIT / PMT에 액세스하려면 느린 I / O 포트 명령을 실행해야하므로 QPC의 실행 시간은 마이크로 초 단위입니다. 반대로 TSC를 읽는 것은 100 클럭 사이클의 순서 (칩에서 TSC를 읽고이를 작동 주파수에 따라 시간 값으로 변환).
아마도 이것이 질문에 대한 대답 일 것입니다. 두 가지 방법은 서로 다른 수의 클럭 사이클을 사용하므로 이후의 클럭 속도가 느려집니다.
결론 섹션의 해당 블로그에서 추가로 :
경과 시간 측정 / 계산에 관심이 있다면 항상 System.nanoTime ()을 사용하십시오. 대부분의 시스템에서는 마이크로 초 단위의 해상도를 제공합니다. 그러나이 호출은 일부 플랫폼 에서 실행 하는 데 마이크로 초가 걸릴 수도 있습니다 .
대부분의 OS (사용중인 OS는 언급하지 않음)에는 밀리 초 정확도 (또는 그에 가까운)를 제공하는 메모리 카운터 / 클럭이 있습니다. 나노초 정확도를 위해 대부분은 하드웨어 카운터를 읽어야합니다. 하드웨어와의 통신 속도가 이미 메모리에있는 일부 값을 읽는 것보다 느립니다.
Windows에서만 해당 될 수 있습니다. 비슷한 질문에 대한 답변 을 참조하십시오 .
기본적으로 System.currentTimeMillis()
Windows에서 유지 관리하는 전역 변수 (낮은 세분성)를 읽는 반면 System.nanoTime()
실제로는 IO 작업을 수행해야합니다.
당신은 Windows에서 그것을 측정하고 있습니다. 2008 년에이 연습을 진행했습니다. nanoTime은 Windows에서 currentTimeMillis보다 느립니다. 내가 기억 하듯이, Linux에서 nanotime은 currentTimeMillis보다 빠르며 확실히 Windows보다 빠릅니다.
주목해야 할 중요한 점은 밀리 초 미만의 여러 작업의 집계를 측정하려는 경우 작업이 1/1000 초 미만의 시간 내에 완료된 것처럼 nanotime을 사용해야하며 currentTimeMillis를 비교하면 작업이 즉각적으로 표시됩니다. 이 중 1,000 개는 여전히 순간적입니다. 원하는 것은 nanotime을 사용한 다음 가장 가까운 밀리 초로 반올림하는 것입니다. 따라서 작업에 8000 나노초가 걸린 경우 0이 아닌 1 밀리 초로 계산됩니다.
원하는 것은 nanotime을 사용한 다음 가장 가까운 밀리 초로 반올림하는 것입니다. 따라서 작업에 8000 나노초가 걸린 경우 0이 아닌 1 밀리 초로 계산됩니다.
산술 참고 :
8000 나노초는 8 마이크로 초는 0.008 밀리 초입니다. 반올림하면 0 밀리 초가됩니다.
'Program Tip' 카테고리의 다른 글
회귀 계수 값 추출 (0) | 2020.12.01 |
---|---|
HTML5 동적으로 캔버스 만들기 (0) | 2020.12.01 |
명령 결과를 bash에서 인수로 사용합니까? (0) | 2020.12.01 |
C #에서 비동기 파일 복사 / 이동 (0) | 2020.12.01 |
CouchDB에서 일반 사용자 만들기 (0) | 2020.12.01 |