본문으로 건너뛰기

"measurement" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분
Green

벤치마킹 테스트를 해보게도 되네요.
폭주하는 서비스를 개발하는것도 아닌데, 그냥 심심풀이로 서핑하다가 보여서 해봤어요.

특징

  • Oracle 에서 JVM 개발하는 분들이 만드셨다고 하고
  • Java9 부터는 공식적으로 JDK에 같이 배포된다고 줴이줴이뤱에 훌륭한 분이 정리한 내용을 참조하면 더 많은 특징을 얻을 수 있겠어요.

시작

당연히 JMH 공식사이트에서 확인하시는게 좋겠죠. 저는 잘 모르면서 막해본거라서...
샘플 코드들이 보고 따라하기 좋은 것 같고요.

준비

프로젝트에 JMH에 관련된 dependency를 추가 해요. 저는 gradle 환경이니까,

...

dependencies {
...
testImplementation 'org.openjdk.jmh:jmh-core:1.21'
testImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.21'
}

이렇게 org.openjdk.jmhjmh-corejmh-generator-annprocess 를 추가하고, IntellJ에 플러그인 을 설치 했어요. 플러그인 없이

import org.openjdk.jmh.annotations.*;

class BenchmarkTest {

...

public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(BenchmarkTest.class.getSimpleName())
.warmupIterations(3)
.measurementIterations(1)
.forks(1)
.build();

new Runner(opt).run();

}
}

이렇게 실행해도 되고요.

실행

최근에 정적분석을 하면서 java.util.Randomjava.security.SecureRandom 으로 바꾸라고 지적된게 있었거든요. 그래서 그 두가지를 벤치마킹 해봤어요.

@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(1)
@Warmup(iterations = 1)
@BenchmarkMode(Mode.Throughput)
@Measurement(iterations = 1)
public class BenchmarkTest {

private final Random random = new Random();

private final SecureRandom secureRandom = new SecureRandom();

@Benchmark
public void measureRandom() {
random.nextDouble();
}

@Benchmark
public void measureSecureRandom() {
secureRandom.nextDouble();
}
}

실행 결과 다음과 같이 리포트 되네요.

# JMH version: 1.21
# VM version: JDK 1.8.0_181, Java HotSpot(TM) 64-Bit Server VM, 25.181-b13
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8
# Warmup: 1 iterations, 10 s each
# Measurement: 1 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: BenchmarkTest.measureRandom

# Run progress: 0.00% complete, ETA 00:00:40
# Fork: 1 of 1
# Warmup Iteration 1: 41945.262 ops/ms
Iteration 1: 42456.015 ops/ms


Result "BenchmarkTest.measureRandom":
42456.015 ops/ms


# JMH version: 1.21
# VM version: JDK 1.8.0_181, Java HotSpot(TM) 64-Bit Server VM, 25.181-b13
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8
# Warmup: 1 iterations, 10 s each
# Measurement: 1 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: BenchmarkTest.measureSecureRandom

# Run progress: 50.00% complete, ETA 00:00:20
# Fork: 1 of 1
# Warmup Iteration 1: 1826.455 ops/ms
Iteration 1: 1837.092 ops/ms


Result "BenchmarkTest.measureSecureRandom":
1837.092 ops/ms


# Run complete. Total time: 00:00:41

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark Mode Cnt Score Error Units
BenchmarkTest.measureRandom thrpt 42456.015 ops/ms
BenchmarkTest.measureSecureRandom thrpt 1837.092 ops/ms

Score 가 42배쯤 차이나니까 그게 성능차이라고 보면 될것 같네요. REMEMBER 부분에 적힌 글을 보니까 그냥 데이터로만 참조하라고 첨언하는 것 같아요. 재사용하는 통찰을 얻으려면 숫자들이 가리키는 걸 따라가라고 하면서요.

맺음

저는 그냥 재미로 '이런것도 있구나' 하고선 시작해봤는데 재사용성을 위해 refactoring을 하면서 채점식으로 수치를 확인해가면, 의욕도 생기고 보람도 생길지는 않을까 싶기도 해요.

더 활용도가 높을텐데 제 수준에서는 이정도 밖에 모르겠네요. 간간히 성능이슈에 활용해서 더 좋은 팁은 또 정리해 봐야겠어요.