Java에서 코드의 실행 시간을 측정하는 방법은 여러 가지가 있으며, 상황에 따라 적합한 방법을 선택할 수 있습니다. 아래는 다양한 케이스에 따른 실행 시간 측정 방법을 소개합니다.
System.nanoTime()은 현재 JVM의 고해상도 시간(나노초 단위)을 제공합니다. 이는 코드의 정확한 실행 시간을 측정할 때 많이 사용됩니다.
public class ExecutionTimeExample {
public static void main(String[] args) {
long startTime = System.nanoTime();
// 실행할 코드
for (int i = 0; i < 1000000; i++) {
Math.sqrt(i);
}
long endTime = System.nanoTime();
long duration = endTime - startTime; // 나노초 단위
System.out.println("Execution time: " + duration + " ns");
}
}
장점: 고해상도 시간 측정.
단점: JVM 초기화 및 GC가 실행 시간에 영향을 줄 수 있음.
System.currentTimeMillis()는 현재 시간을 밀리초 단위로 반환합니다. 상대적으로 덜 정밀하지만 대략적인 시간을 측정할 때 적합합니다.
public class ExecutionTimeExample {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
// 실행할 코드
for (int i = 0; i < 1000000; i++) {
Math.sqrt(i);
}
long endTime = System.currentTimeMillis();
long duration = endTime - startTime; // 밀리초 단위
System.out.println("Execution time: " + duration + " ms");
}
}
장점: 간단하고 직관적.
단점: 정밀도가 낮음.
Java 8 이상에서는 java.time 패키지를 활용하여 시간을 측정할 수 있습니다.
import java.time.Duration;
import java.time.Instant;
public class ExecutionTimeExample {
public static void main(String[] args) {
Instant start = Instant.now();
// 실행할 코드
for (int i = 0; i < 1000000; i++) {
Math.sqrt(i);
}
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("Execution time: " + duration.toMillis() + " ms");
}
}
장점: 가독성이 높고, 기간(Duration) 객체를 통해 다양한 시간 단위(나노초, 밀리초 등)로 변환 가능.
단점: 약간의 오버헤드.
Spring Framework의 StopWatch 유틸리티를 사용하면 실행 시간을 보다 체계적으로 관리할 수 있습니다.
import org.springframework.util.StopWatch;
public class ExecutionTimeExample {
public static void main(String[] args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 실행할 코드
for (int i = 0; i < 1000000; i++) {
Math.sqrt(i);
}
stopWatch.stop();
System.out.println("Execution time: " + stopWatch.getTotalTimeMillis() + " ms");
}
}
장점: 다양한 작업을 단계별로 측정 가능 (startTask(), stop()).
단점: Spring 라이브러리가 필요함.
JMH는 Java에서 마이크로벤치마킹을 위해 설계된 프레임워크로, JVM의 최적화 효과를 배제하고 정확한 실행 시간을 측정합니다.
import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 평균 실행 시간
@OutputTimeUnit(TimeUnit.MILLISECONDS) // 출력 단위
@State(Scope.Thread)
public class ExecutionTimeExample {
@Benchmark
public void testExecutionTime() {
for (int i = 0; i < 1000000; i++) {
Math.sqrt(i);
}
}
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
}
장점: 정확하고 신뢰도 높은 측정.
단점: 설정 및 사용법이 다소 복잡함.
멀티스레드 프로그램에서 특정 스레드의 CPU 시간을 측정하려면 ThreadMXBean을 사용할 수 있습니다.
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
public class ExecutionTimeExample {
public static void main(String[] args) {
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long startCpuTime = bean.getCurrentThreadCpuTime();
// 실행할 코드
for (int i = 0; i < 1000000; i++) {
Math.sqrt(i);
}
long endCpuTime = bean.getCurrentThreadCpuTime();
long duration = (endCpuTime - startCpuTime) / 1_000_000; // 밀리초 단위
System.out.println("CPU time: " + duration + " ms");
}
}
장점: CPU 사용 시간 측정 가능.
단점: 실제 벽 시간(wall-clock time)과는 다름.
방법 | 정밀도 | 설치 필요 여부 | 장점 | 단점 |
System.nanoTime() | 높음 | 불필요 | 고정밀도 | JVM의 GC 및 오버헤드 영향 가능 |
System.currentTimeMillis() | 중간 | 불필요 | 간단하고 사용법이 직관적 | 정밀도 낮음 |
Instant와 Duration | 높음 | Java 8 필요 | 가독성이 높고 다양한 단위 변환 가능 | 약간의 오버헤드 |
StopWatch | 높음 | Spring 필요 | 체계적인 측정 및 태스크 관리 | Spring 의존성 필요 |
JMH | 매우 높음 | 필요 | JVM 최적화 배제, 정확한 마이크로벤치마킹 가능 | 설정 복잡 |
ThreadMXBean | 중간 | 불필요 | 특정 스레드의 CPU 시간 측정 가능 | 벽 시간(wall time)과 다름 |
위에서 제시된 방법들을 적절히 활용하여 자바 코드의 성능을 분석하고 개선하는 데 도움이 되기를 바랍니다.
[JAVA] List, ArrayList, LinkedList 차이점 분석 (1) | 2024.11.29 |
---|---|
[JAVA] 자바 21 버전 특징 및 새로운 기능 (1) | 2024.11.28 |
[JAVA] 1.8, 11, 17 버전별 차이에 대해서 알아보자 (0) | 2024.11.27 |
[JAVA] 접근 제어자(private, protected, public) 차이점 (0) | 2024.11.26 |
[JAVA] User-Agent를 통해서 PC/MOBILE 구분하는 방법 (0) | 2022.11.01 |