경과 시간(Elapsed Time)이란 일반적으로 하나의 작업이나 이벤트가 시작되는 시점부터 끝나는 시점까지 걸린 시간을 의미합니다. Java에서는 성능 분석이나 프로파일링을 위해 다양한 방식으로 메서드의 실행 시간을 측정할 수 있습니다. 이번 글에서는 가장 많이 사용되는 네 가지 방법을 예제 코드와 함께 살펴보겠습니다.
1. currentTimeMillis() 메서드 사용
System.currentTimeMillis() 메서드는 현재 시간을 밀리초(millisecond) 단위로 반환합니다. 측정하고자 하는 메서드 실행 전과 후에 각각 시간 값을 구한 뒤, 두 값의 차이를 계산하면 해당 메서드의 경과 시간을 구할 수 있습니다.
예제 코드
public class Example {
public void test(){
int num = 0;
for(int i=0; i<=50; i++){
num =num+i;
System.out.print(num+", ");
}
}
public static void main(String args[]){
// 시작 시간
long begin = System.currentTimeMillis();
// 메서드 실행
new Example().test();
// 종료 시간
long end = System.currentTimeMillis();
long time = end-begin;
System.out.println();
System.out.println("Elapsed Time: "+time +" milli seconds");
}
}
실행 결과
0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465, 496, 528, 561, 595, 630, 666, 703, 741, 780, 820, 861, 903, 946, 990, 1035, 1081, 1128, 1176, 1225, 1275, Elapsed Time: 4 milli seconds
2. nanoTime() 메서드 사용
System.nanoTime() 메서드는 현재 시간을 나노초(nanosecond) 단위로 반환합니다. 밀리초 단위보다 훨씬 정밀한 측정이 필요할 때 유용하며, 마찬가지로 메서드 실행 전후의 시간 값 차이를 계산하여 경과 시간을 구합니다.
참고로 nanoTime()은 실제 벽시계 시간(wall-clock time)이 아닌 임의의 기준점부터 경과한 시간을 나타내므로, 두 시점의 차이를 계산하는 용도로만 사용해야 합니다.
예제 코드
public class Example {
public void test(){
int num = 0;
for(int i=0; i<=50; i++){
num =num+i;
System.out.print(num+", ");
}
}
public static void main(String args[]){
// 시작 시간
long begin = System.nanoTime();
// 메서드 실행
new Example().test();
// 종료 시간
long end = System.nanoTime();
long time = end-begin;
System.out.println();
System.out.println("Elapsed Time: "+time);
}
}
실행 결과
0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465, 496, 528, 561, 595, 630, 666, 703, 741, 780, 820, 861, 903, 946, 990, 1035, 1081, 1128, 1176, 1225, 1275, Elapsed Time: 1530200
3. Instant 클래스 사용
Java 8부터 도입된 날짜·시간 API인 java.time 패키지의 Instant 클래스를 활용하는 방법도 있습니다. Instant.now() 메서드는 현재 시각을 반환하며, Duration.between() 메서드는 주어진 두 시점 사이의 차이를 계산합니다.
메서드 실행 전후의 시각을 각각 구한 뒤, Duration.between()으로 두 시점 사이의 지속 시간(Duration)을 얻으면 됩니다.
예제 코드
import java.time.Duration;
import java.time.Instant;
public class Example {
public void test(){
int num = 0;
for(int i=0; i<=50; i++){
num =num+i;
System.out.print(num+", ");
}
}
public static void main(String args[]) {
// 시작 시간
Instant start = Instant.now();
new Example().test();
// 종료 시간
Instant end = Instant.now();
long time = Duration.between(start, end).toMillis();
System.out.println();
System.out.println(time+" Milli seconds");
}
}
실행 결과
0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465, 496, 528, 561, 595, 630, 666, 703, 741, 780, 820, 861, 903, 946, 990, 1035, 1081, 1128, 1176, 1225, 1275, 3 Milli seconds
4. StopWatch 클래스 사용
Apache Commons Lang 라이브러리에서 제공하는 StopWatch 클래스를 사용하면 더욱 직관적으로 시간을 측정할 수 있습니다. 이 클래스는 스톱워치처럼 동작하며, start(), stop(), getTime() 메서드를 통해 메서드 실행에 걸린 시간을 손쉽게 확인할 수 있습니다.
다음은 이 라이브러리를 사용하기 위한 Maven 의존성 설정입니다.
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency>
예제 코드
import org.apache.commons.lang3.time.StopWatch;
public class Example {
public void test(){
int num = 0;
for(int i=0; i<=50; i++){
num =num+i;
System.out.print(num+", ");
}
}
public static void main(String args[]) {
// StopWatch 객체 생성
StopWatch obj = new StopWatch();
// 스톱워치 시작
obj.start();
new Example().test();
// 스톱워치 정지
obj.stop();
System.out.println();
System.out.println("Elapsed Time: "+obj.getTime() +" milli seconds");
}
}
실행 결과
0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465, 496, 528, 561, 595, 630, 666, 703, 741, 780, 820, 861, 903, 946, 990, 1035, 1081, 1128, 1176, 1225, 1275, Elapsed Time: 1 milli seconds
마무리: 어떤 방법을 선택해야 할까?
간단한 성능 측정에는 currentTimeMillis()로 충분하지만, 짧은 실행 시간을 정밀하게 측정해야 한다면 nanoTime()이 적합합니다. Java 8 이상 환경에서는 모던 API인 Instant와 Duration 조합을 권장하며, 여러 구간의 시간을 측정하거나 가독성 높은 코드가 필요하다면 Apache Commons의 StopWatch 클래스가 좋은 선택입니다. 상황에 맞는 방법을 골라 효율적으로 성능을 분석해 보세요.