0Pricing
Java Academy · 강의

JMH가 필요한 이유

순진한 벤치마크 실수를 피합니다

JMH가 필요한 이유은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

JMH를 사용하는 이유

Java 마이크로벤치마크 하네스(JMH)는 작은 Java 코드 조각의 성능을 측정하는 표준 도구입니다. JVM은 정교한 최적화 실행 환경이므로, 직접 작성한 시간 측정 반복문은 거의 항상 잘못된 수치를 냅니다.

JMH는 이러한 문제를 무력화하기 위해 존재합니다.

단순한 벤치마크

일반적인 첫 시도는 반복문을 System.nanoTime()으로 감싸는 것입니다. 합리적으로 보이지만 마이크로벤치마크에는 심각한 문제가 있습니다.

public class Main {
    static int compute(int n) { return n * n + 7; }
    public static void main(String[] args) {
        long start = System.nanoTime();
        int sink = 0;
        for (int i = 0; i < 1_000_000; i++) sink = compute(i);
        long elapsed = System.nanoTime() - start;
        System.out.println("ns: " + elapsed + " sink=" + sink);
    }
}

문제 1: JIT 워밍업

JVM은 해석 모드에서 시작하며, 수천 번 호출된 후에야 자주 실행되는 메서드를 네이티브 코드로 컴파일합니다. 단순한 벤치마크는 느린 해석 단계와 빠른 컴파일 단계를 함께 측정하므로 의미 없는 평균을 냅니다.

JMH는 별도의 워밍업 단계를 실행한 뒤 그 결과를 버려 이 문제를 해결합니다.

문제 2: 죽은 코드 제거

계산한 결과를 전혀 사용하지 않으면 JIT가 계산 자체를 완전히 삭제할 수 있습니다. 그러면 벤치마크는 빈 반복문을 측정하게 됩니다.

JMH는 반환 값 소비와 Blackhole을 제공하여 이를 방지합니다.

문제 3: 상수 접기

입력이 컴파일 시점의 상수라면 JIT가 답을 한 번 계산한 뒤 재사용합니다. 아래 코드에서는 컴파일러가 전체 반복문을 단일 상수로 바꿀 수 있습니다.

JMH는 @State 객체를 사용하여 최적화기가 입력을 알 수 없게 만듭니다.

public class Main {
    public static void main(String[] args) {
        // 2 * 21 is constant; the JIT folds it to 42
        int result = 2 * 21;
        System.out.println(result);
    }
}

문제 4: 반복문 최적화

JIT는 반복문을 펼치고, 변하지 않는 코드를 반복문 밖으로 옮기며, 연산을 벡터화합니다. 직접 작성한 반복문을 사용하면 의도한 연산이 아니라 이러한 최적화를 측정하게 됩니다.

JMH는 직접 관리하는 정밀하게 제어된 반복 횟수로 반복문을 대체합니다.

문제 5: 스택 상 교체

main의 오래 실행되는 반복문은 실행 중간에 컴파일될 수 있습니다(스택 상 교체). 그러면 일반적으로 컴파일된 메서드와 다른 성능 특성이 나타납니다. 이 때문에 결과가 예측할 수 없이 왜곡됩니다.

JMH가 제공하는 기능

  • 별도로 실행한 뒤 버리는 워밍업 반복 실행
  • 통계가 포함된 여러 측정 반복 실행
  • 이전 벤치마크로 인한 프로파일 오염을 피하기 위한 새로운 JVM에서의 포크 실행
  • 죽은 코드 제거를 방지하는 블랙홀과 결과 소비
  • 상수 접기를 막는 @State 객체

실행 방법

JMH는 별도의 의존성(org.openjdk.jmh)이며, 일반적으로 주석 처리기와 실행 가능한 JAR을 생성하는 Maven/Gradle 빌드를 통해 실행합니다. 일반 코드처럼 단순한 main에서 벤치마크를 실행하지는 않습니다.

통계가 중요한 이유

JMH는 평균뿐 아니라 여러 반복 실행과 포크 실행에 걸친 오차 / 신뢰 구간도 보고합니다. 42.0 +/- 1.3 ns/op이라는 결과는 중심값과 값이 얼마나 변했는지를 모두 알려 주므로, 측정 결과를 신뢰하는 데 필수적입니다.

JMH를 사용해야 할 때

자주 실행되는 경로의 두 구현을 비교하거나, 최적화를 검증하거나, 나노초에서 마이크로초 단위의 연산을 측정할 때 JMH를 사용하세요. 입출력이나 네트워크처럼 초 단위로 대략 측정하는 작업에는 일반적으로 실제 경과 시간 측정만으로 충분합니다.

빠른 확인

JMH가 필요한 이유를 얼마나 이해했는지 확인해 보세요.

복습

마이크로벤치마크에 하네스가 필요한 이유를 배웠습니다:

  • JVM은 워밍업됩니다. 해석된 코드는 많은 호출이 이루어진 후에야 컴파일된 코드가 됩니다.
  • 죽은 코드 제거와 상수 접기는 작업을 삭제하거나 미리 계산할 수 있습니다.
  • 반복문 최적화와 스택 상 교체는 직접 작성한 반복문을 왜곡합니다.
  • JMH는 워밍업, 측정 반복 실행, 포크 실행, 블랙홀 및 통계를 추가합니다.
  • 나노초 단위의 자주 실행되는 경로를 측정할 때 사용하세요.

자주 묻는 질문

“JMH가 필요한 이유” 강의는 무료인가요?

네 — “JMH가 필요한 이유” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“JMH가 필요한 이유”에서 뭘 배우나요?

순진한 벤치마크 실수를 피합니다 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Java Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“JMH가 필요한 이유” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. JMH가 필요한 이유
  2. 벤치마크 작성
  3. 워밍업과 반복
  4. 죽은 코드 제거 방지
← Java Academy(으)로 돌아가기