반응형
이 포스팅에서 작성하는 내용은 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 |