[Effective Java] 아이템 48. 스트림 병렬화는 주의해서 적용하라

2022. 11. 9. 22:36· BE/Java
목차
  1. 아이템 48. 스트림 병렬화는 주의해서 적용하라
  2. 정리
반응형

EFFECTIVE JAVA(이펙티브 자바)

 

이 포스팅에서 작성하는 내용은 EFFECTIVE JAVA(이펙티브자바) 에서 발췌하였습니다.


아이템 48. 스트림 병렬화는 주의해서 적용하라

 

병렬화

  • 자바 8부터 parallel 메서드만 한 번 호출하면 파이프라인을 병렬 실행시할 수 있는 스트림을 지원한다.
  • 동시성 프로그래밍을 할 떄는 안정성과 응답 가능 상태를 유지해야 하는데, 병렬 스트림 파이프라인 프로그래밍에서도 마찬가지이다.

 

ex 1) 스트림을 사용해 처음 20개의 메르센 소수를 생성하는 프로그램

public static void main(String[] args) {
	primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
			.filter(mersenne -> mersenne.isProbablePrime(50))
			.limit(20)
			.forEach(System.out::println);
}

static Stream<BigInteger> primes() {
	return Stream.iterate(TWO, BigInteger::nextProbablePrime);
}
  • 메르센 소수 : 2의 거듭제곱에서 1이 모자란 숫자
  • 속도를 높이고 싶어 스트림 파이프라인의 parallel()을 호출하면 프로그램이 먹통이 된다.
    • 스트림 라이브러리가 이 파이프라인을 병렬화하는 방법을 찾아내지 못했기 때문이다.
    • 데이터 소스가 Stream.iterate거나 중간 연산으로 limit를 쓰면 파이프라인 병렬화로는 성능 개선을 기대할 수 없다.
  • 대체로 스트림의 소스가 ArrayList, HashMap, HashSet, ConcurrentHashMap의 인스턴스거나 배열, int 범위, long 범위일 때 병렬화의 효과가 가장 좋다.
    • 이 자료구조들은 데이터를 원하는 크기로 정확하게 나눌 수 있어서 다수의 스레드에 분배하기 좋다.
    • 나누는 작업은 Spliterator가 담당하며, Spliterator 객체는 Stream이나 Iterable의 spliterator 메서드로 얻어올 수 있다.
    • 원소들을 순차적으로 실행할 때의 참조 지역성이 뛰어나 병렬 시 빠르게 메모리를 참조할 수 있다.
  • 즉, 스트림을 잘못 병렬화하면 성능이 안좋아질 뿐만 아니라 결과 자체가 잘못되거나 예상 못한 동작이 발생할 수 있다.

 

 

ex 2) 소수 계산 스트림 파이프라인(병렬화가 필요)

static long pi(long n) {
    return LongStream.rangeClosed(2, n)
            .mapToObj(BigInteger::valueOf)
            .filter(i -> i.isProbablePrime(50))
            .count();
}
  • 소요 시간 : 31초 (저자의 컴퓨터 기준)

 

ex 3) 소수 계산 스트림 파이프라인(병렬화 작업 완료)

static long pi(long n) {
    return LongStream.rangeClosed(2, n)
            **.parallel()** 
            .mapToObj(BigInteger::valueOf)
            .filter(i -> i.isProbablePrime(50))
            .count();
}
  • 소요 시간 : 9.2초 (저자의 컴퓨터 기준)
  • 조건이 잘 갖춰지면 parallel 메서드 호출로도 거의 프로세서 코어 수와 비례하는 성능 향상을 할 수 있다.

 

 

정리

  • 정확한 확신 없이는 무턱대고 스트림 파이프라인 병렬화를 진행하지 말자
  • 스트림 병렬화를 잘못 진행하면 오히려 안좋아 진다.
  • 병렬화하는 편이 낫다고 생각하더라도, 수정 후의 코드가 여전히 정확한지 확인하고 운영 환경과 유사한 조건에서 수행해보며 성능지표를 관찰하자
반응형

'BE > Java' 카테고리의 다른 글

[Effective Java] 아이템 50. 적시에 방어적 복사본을 만들라  (0) 2022.11.11
[Effective Java] 아이템 49. 매개변수가 유효한지 검사하라  (0) 2022.11.10
[Effective Java] 아이템 47. 반환 타입으로는 스트림보다 컬렉션이 낫다.  (0) 2022.11.08
[Effective Java] 아이템 46. 스트림에서는 부작용 없는 함수를 사용하라  (0) 2022.11.07
[Effective Java] 아이템 45. 스트림은 주의해서 사용하라  (1) 2022.11.04
  1. 아이템 48. 스트림 병렬화는 주의해서 적용하라
  2. 정리
'BE/Java' 카테고리의 다른 글
  • [Effective Java] 아이템 50. 적시에 방어적 복사본을 만들라
  • [Effective Java] 아이템 49. 매개변수가 유효한지 검사하라
  • [Effective Java] 아이템 47. 반환 타입으로는 스트림보다 컬렉션이 낫다.
  • [Effective Java] 아이템 46. 스트림에서는 부작용 없는 함수를 사용하라
멍목
멍목
개발 관련 새롭게 알게 된 지식이나 좋은 정보들을 메모하는 공간입니다.
반응형
멍목
김멍목의 개발블로그
멍목
전체
오늘
어제
  • 분류 전체보기 (514)
    • BE (190)
      • Spring (21)
      • Java (141)
      • Kotlin (6)
      • JPA (22)
    • FE (33)
      • Javascript (16)
      • Typescript (0)
      • React (5)
      • Vue.js (9)
      • JSP & JSTL (3)
    • DB (32)
      • Oracle (22)
      • MongoDB (10)
    • Algorithm (195)
    • Linux (8)
    • Git (6)
    • etc (42)
    • ---------------------------.. (0)
    • 회계 (4)
      • 전산회계 2급 (4)
    • 잡동사니 (2)

블로그 메뉴

  • 홈
  • 관리

공지사항

인기 글

태그

  • Java to Kotlin
  • JPA
  • 자기공부
  • vue3 공부
  • 자바 테스팅 프레임워크
  • 더 자바 Java 8
  • 코테 공부
  • 프로젝트로 배우는 Vue.js 3
  • 전산회계 2급 준비
  • Effective Java
  • MongoDB 기초부터 실무까지
  • 자기개발
  • 이펙티브자바
  • MongoDB 공부
  • 알고리즘공부
  • junit5
  • 자기 개발
  • 코테공부
  • 이펙티브 자바
  • JPA 공부
  • 코틀린
  • 자기 공부
  • 자바공부
  • java 8
  • 자바 공부
  • 알고리즘 공부
  • 더 자바 애플리케이션을 테스트하는 다양한 방법
  • 자바 개발자를 위한 코틀린 입문
  • MongoDB with Node.js
  • Oracle

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
멍목
[Effective Java] 아이템 48. 스트림 병렬화는 주의해서 적용하라
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.