Skip to content

Latest commit

 

History

History
39 lines (23 loc) · 2.6 KB

item48.md

File metadata and controls

39 lines (23 loc) · 2.6 KB

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

자바 8부터는 parallel 메소드만 한 번 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원했습니다.

동시성 프로그래밍을 할 때는 안전성(safety)응답 가능(liveness) 상태를 유지해야 합니다.

책 P291의 48-1를 보면 메르센 소수를 생성하는 코드가 있습니다.

그런데 시간이 오래 걸려서 스트림 파이프라인의 parallel()을 호출해보겠습니다.

그러면 스트림 라이브러리가 이 파이프라인을 병렬화하는 방법을 찾아내지 못하기 때문에 아무 결과도 출력하지 않습니다.

데이터 소스가 Stream.iterate거나 중간 연산으로 limit를 쓰면 파이프라인 병렬화로는 성능 개선을 기대할 수 없다.

  • 파이프라인 병렬화는 limit를 다룰 때 CPU 코어가 남는다면 원소를 몇 개 더 처리한 후 제한된 개수 이후의 결과를 버려도 아무런 해가 없다고 가정합니다.
  • 원소 하나를 계산하는 비용이 대략 그 이전까지의 원소 전부를 계산한 비용을 합친 것만큼 든다는 뜻입니다. (P292 아래에 설명이 나옵니다.)

스트림 소스가 ArrayList, HashMap, HashSet, ConcurrentHashMap의 인스턴스거나 배열, int 범위, long 범위일 때 병렬화의 효과가 좋다.

  • 위의 자료구조는 데이터를 원하는 크기로 정확하고 손쉽게 나눌 수 있어 다수의 스레드에 일을 분배하기 좋다는 특징이 있습니다.
  • 참조 지역성(원소 참조들이 메모리에 연속에서 저장되어 있음)이 뛰어납니다.
    • 참조 지역성이 낮으면 데이터가 주 메모리에서 캐시 메모리로 전송되어 오기를 기다리며 대부분 시간을 멍하니 보내게 됩니다.

스트림을 잘못 병렬화하면 성능이 나빠질 뿐만 아니라 결과 자체가 잘못되거나 예상 못한 동작이 발생할 수 있다.

예를들어, Stream의 reduce 연산에 건네지는 accumulator와 combiner 함수는 반드시 결합법칙을 만족하고, 간섭 받지 않는 상태를 갖지 않아야 합니다.


핵심 정리

  • 스트림 병렬화는 오직 성능 최적화 수단임을 기억하자.
  • 스트림을 잘못 병렬화하면 오작동하게 하거나 성능을 떨어뜨린다.
  • 성능 테스트를 하여 병렬화를 사용할 가치가 있는지 확인하기
  • 조건이 잘 갖춰지면 parallel 메소드 호출 하나로 거의 프로세서 코어 수에 비레하는 성능 향상을 볼 수 있다.