스터디/이펙티브 자바

[Effective Java] Item48. 스트림 병렬화는 주의해서 사용하라

📝 작성 : 2022.07.10  ⏱ 수정 : 

병렬화는 신중히

병렬화를 잘 못 사용하면 오히려 성능이 더 나빠질 수 있기 때문에 주의해서 사용해야 합니다.

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);
}

성능을 기대하고 paralle()을 호출하면 아무것도 출력하지 못합니다. 이는 스트림이 파이프라인을 병렬화하는 방법을 찾지 못했기 때문입니다.
데이터 소스가 Stream.iterate()이거나 중간 연산으로 limit()를 사용하면 병렬화로는 성능개선을 기대할 수 없습니다.

병렬화하기 좋은 경우

이웃한 원소의 참조들이 메모리에 연속적으로 저장되어있으며, 데이터를 원하는 크기로 나눌 수 있는 자료형이 좋습니다.
대표적으로 ArrayList, HashMap, HashSet, ConcurrentHashMap, 배열, int, long 등이 있습니다.

종단 연산

종단 연산에서 수행하는 작업량이 파이프라인 전체 작업에서 상당 비중으로 차지하며, 순차적인 연산이라면 파이프라인 병렬 수행의 효과는 제한적입니다.
종단 연산 중 병렬화에 적합한 것은 축소(reduction)입니다.

  • reduce()
  • min(), max(), count(), sum()
  • anyMatch(), allMatch(), noneMatch()

반면 collect()는 병렬화에 적합하지 않습니다.

반응형