에스제이

반응형

 

Java에서 코드의 실행 시간을 측정하는 방법은 여러 가지가 있으며, 상황에 따라 적합한 방법을 선택할 수 있습니다. 아래는 다양한 케이스에 따른 실행 시간 측정 방법을 소개합니다.

 

1. System.nanoTime() 이용

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가 실행 시간에 영향을 줄 수 있음.

 

2. System.currentTimeMillis() 이용

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");
    }
}

 

장점: 간단하고 직관적.

단점: 정밀도가 낮음.

 

3. Instant와 Duration (Java 8 이상)

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) 객체를 통해 다양한 시간 단위(나노초, 밀리초 등)로 변환 가능.

단점: 약간의 오버헤드.

 

4. StopWatch (Spring Framework)

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 라이브러리가 필요함.

 

5. JMH (Java Microbenchmark Harness)

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);
    }
}

 

장점: 정확하고 신뢰도 높은 측정.

단점: 설정 및 사용법이 다소 복잡함.

 

6. ThreadMXBean (멀티스레드 환경에서 CPU 시간 측정)

멀티스레드 프로그램에서 특정 스레드의 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)과는 다름.

 

7. 정리

방법 정밀도 설치 필요 여부 장점 단점
System.nanoTime() 높음 불필요 고정밀도 JVM의 GC 및 오버헤드 영향 가능
System.currentTimeMillis() 중간 불필요 간단하고 사용법이 직관적 정밀도 낮음
Instant와 Duration 높음 Java 8 필요 가독성이 높고 다양한 단위 변환 가능 약간의 오버헤드
StopWatch 높음 Spring 필요 체계적인 측정 및 태스크 관리 Spring 의존성 필요
JMH 매우 높음 필요 JVM 최적화 배제, 정확한 마이크로벤치마킹 가능 설정 복잡
ThreadMXBean 중간 불필요 특정 스레드의 CPU 시간 측정 가능 벽 시간(wall time)과 다름

 

위에서 제시된 방법들을 적절히 활용하여 자바 코드의 성능을 분석하고 개선하는 데 도움이 되기를 바랍니다.

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band