System.currentTimeMillis 와 System.nanoTime의 차이가 뭔가요?
조회수 18120회
1 답변
-
"시간"의 용도?
시스템에서 "시간"은 크게 두 가지 용도로 사용됩니다. 첫 번째는 말 그대로 시각(시/분/초)을 표현하기 위한 용도이고, 두 번째는 스케줄링이나 이벤트 처리를 위한 타이머 용도입니다. 오라클의 Davidholmes는 각각을 "passive clock"과 "active clock"으로 표현하기도 했습니다. 이 두 가지 시간을 각각 반환하는 메서드가 바로 currentTimeMillis와 nanoTime입니다.
currentTimeMillis 메서드
우선 간단한 코드로 currentTimeMillis 메서드의 결과를 살펴보겠습니다.
public class CurrentTimeMillisTest { public static void main(String[] args) { long currentTime = System.currentTimeMillis(); System.out.println("current time value = " + currentTime); System.exit(0); } }
current time value = 1335895964247
currentTimeMillis 메서드는 UTC 시간 즉, 1970년 1월 1일 자정부터 현재까지 카운트된 시간을 ms(milliseconds) 단위로 표시합니다. 따라서 출력 결과는 1970년 1월 1일 UTC 시작 시점으로부터 현재까지 총 1335895964247(ms) 만큼의 시간이 흘렀음을 말해주는 것입니다. 이 값을 각각 시/분/초로 계산해 보면 현재 시각(GMT+0)을 얻을 수 있습니다.
그럼 currentTimeMillis 메서드로 특정 코드의 수행 시간을 계산해 봅시다.
public class CurrentTimeMillisTest { public static void doHardWork(int n, int m) { int result = 1; for(int i=0; i<n; i++) for(int j=0; j<m; j++) for(int k=0; k<n+m; k++) for(int l=0; l<n*m; l++) result *= 2; } public static void main(String[] args) { long startTime = System.currentTimeMillis(); doHardWork(100, 100); long endTime = System.currentTimeMillis(); long elapsedTime = endTime - startTime; System.out.println("Total elapsed time = " + elapsedTime); System.exit(0); } }
Total elapsed time = 11844 위 코드에서 startTime과 endTime 사이에 어느 정도 계산시간을 요하는 doHardWork 메서드를 실행하고 결과를 확인해 보니 대략 11.844초가 나왔습니다. currentTimeMillis 메서드로 특정 코드의 수행 시간을 측정하는데 아무런 문제가 없어보입니다. 그렇다면 nanoTime 메서드는 왜 제공되는 것일까요?
nanoTime 메서드
레퍼런스에 따르면 nanoTime 메서드는 현재 Java 가상머신의 high-resolution 시간값을 ns(nano sec.) 단위로 반환한다고 되어 있고, 이 메서드는 오직 경과된 시간을 측정하는데 사용해야하고, 시스템이나 시각(시/분/초)과는 아무런 연관성이 없음을 말해주고 있습니다. 그럼 간단한 테스트 코드로 nanoTime 메서드의 반환값과 특정 코드의 수행 시간을 계산해 봅시다.
public class NanoTimeTest { public static int doHardWork(int n, int m) { int result = 1; for(int i=0; i<n; i++) for(int j=0; j<m; j++) for(int k=0; k<n+m; k++) for(int l=0; l<n*m; l++) result *= 2; return result; } public static void main(String[] args) { long startTime = System.nanoTime(); System.out.println("start nano-time = " + startTime); doHardWork(100, 100); long endTime = System.nanoTime(); System.out.println("end nano-time = " + endTime); long elapsedTime = endTime - startTime; System.out.println("total elapsed time = " + elapsedTime); System.exit(0); } }
start nano-time = 583086181421940 end nano-time = 583098045092043 total elapsed time = 11863670103
출력 결과를 확인해 보면 대략 11.86초가 경과되었음을 알 수 있습니다.
비교
레퍼런스와 기타 참고문서를 토대로 두 메서드를 비교해 정리하면,
- currentTimeMillis()
- 날짜와 관련한 시각 계산을 위해 사용(ms 단위)
- 시스템 시간을 참조(외부데이터)
- 일반적인 업데이트 간격은 인터럽트의 타이머(10microsec)에 따름
- GetSystemTimeAsFileTime 메서드로 구현되어 있으며, 운영체제가 관리하는 시간값을 가져옴
- nanoTime()
- 기준 시점에서 경과 시간을 측정하는데 사용(ns 단위)
- 시스템 시간과 무관
- QueryPerformanceCounter/QueryPerformanceFrequency API로 구현되어 있음.
결론
코드의 수행시간 계산은 nanoTime 메서드를, 시각(시/분/초) 계산은 currentTimeMillis 메서드를 사용하자!!
- currentTimeMillis()
댓글 입력