BanditBool2 / ReadingRecord

2 stars 0 forks source link

[Ch 7] 7.1.2 스트림 성능 측정 #37

Closed JinseoPark-bd closed 1 year ago

JinseoPark-bd commented 1 year ago

자바 Gradle Build로 스트림 성능 측정하기

자바 마이크로벤치마크 하니스(JMH) 라이브러리를 이용해 벤치마크를 구현할 수 있습니다. 책에서는 Maven Build 도구를 사용하여 구현하였는데, 저는 Gradle Build 도구를 사용하였습니다. 딱히 어려운 점은 없었습니다.

//build.gradle 파일에서

plugins {
    id 'java'
    id 'me.champeau.jmh' version '0.6.6'  //gradle 버전에 맞게 버전을 설정할 수 있습니다.
}

jmh {
    fork =                 // 실행 횟수 지정 
    warmupIterations =     // warm up 수행 횟수 지정
    iterations =           // 측정 횟수 지정 
}

이렇게 추가해주면 설정은 끝납니다.

책에 있는 예제 코드를 실행하였습니다.

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime) // 실행하는데 걸린 평균 시간 측정
@OutputTimeUnit(TimeUnit.MILLISECONDS) // 밀리초 단위로 출력
@Fork(value = 2, jvmArgs = { "-Xms4G", "-Xmx4G" }) // 4Gb의 힙 공간을 제공한 환경에서 두 번 벤치마크를 수행해 결과의 신뢰성 확보
@Measurement(iterations = 2)
@Warmup(iterations = 3)
public class ParallelStreamBenchmark {

  private static final long N = 10_000_000L;

  @Benchmark // 벤치마크 대상 메서드 표시
  public long iterativeSum() {
    long result = 0;
    for (long i = 1L; i <= N; i++) {
      result += i;
    }
    return result;
  }

  @Benchmark
  public long sequentialSum() {
    return Stream.iterate(1L, i -> i + 1).limit(N).reduce(0L, Long::sum);
  }

  @Benchmark
  public long parallelSum() {
    return Stream.iterate(1L, i -> i + 1).limit(N).parallel().reduce(0L, Long::sum);
  }

  @Benchmark
  public long rangedSum() {
    return LongStream.rangeClosed(1, N).reduce(0L, Long::sum);
  }

  @Benchmark
  public long parallelRangedSum() {
    return LongStream.rangeClosed(1, N).parallel().reduce(0L, Long::sum);
  }

  @TearDown(Level.Invocation) // 매 번 벤치마크를 실행한 다음에는 가비지 컬렉터 동작 시도
  public void tearDown() {
    System.gc();
  }

}

대망의 실행 결과입니다....

결과

그냥 병렬로 실행한다고 좋은 성능을 발휘하는 것이 아니라 올바른 자료구조를 선택해야 병렬 실행도 최적의 성능을 발휘할 수 있다고 합니다.

( 책에서처럼 rangedSum에 병렬 스트림을 추가한 parallelRangedSum이 더 성능이 좋게 나와야 하는데, 성능이 더 않좋게 나왔네요.. 원인을 찾아보겠습니다.)

jmh 플러그인 깃허브 참고 블로그

kkambbak commented 1 year ago

저도 이거 찾아보고 있었는데, 진서님이 해주셨군요... 만약 가능하시다면 예시 코드를 커밋해서 올려주시면 좋을 것 같습니다.

그러면 왜 저렇게 결과값이 나오는지 같이 확인해볼 수 있지 않을까요?

그리고 어떤 input값을 사용하셨는지도 궁금합니다. 만약 책처럼 짧은 내용이었다면, iterativeSum이 가장 좋게 나올거 같아서요.