• 주류 언어 중, 동시성 프로그래밍 측면에서 자바는 항상 앞서갔다.

 

  • 자바로 동시성 프로그램을 작성하기가 점점 쉬워지고는 있지만, 이를 올바르고 바르게 작성하는 일은 여전히 어려운 작업이다.
  • 스트림은 기본적으로 싱글 스레드 작업 처리지만, 멀티스레드 환경으로 바꿀 수 도 있다.

 

  • 그러나 적절한 환경에서 사용하지 않는다면 싱글 스레드보다 느려질 수 있다.
    • 데이터 소스가 Stream.iterate거나 중간연산으로 limit를 쓰면 파이프라인 병렬화로는 성능 개선을 할 수 없다.

 

  • 병렬화의 효과가 가장 좋은 스트림 소스
    • HashMap
    • ArrayList
    • HashSet
    • ConcurrentHashMap의 인스턴스거나 배열
    • int 범위
    • long 범위

 

  • 위 자료구조들은 모두 데이터를 원하는 크기로 정확하고손쉽게 나눌 수 있어서 일을 다수의 스레드에 분배하기 좋다.
  • 나누는 작업은 Spliterator가 담당하며 Spliterator 객체는 Stream이나 Iterable의 spliterator 메소드로 얻어올 수 있다.
  • 또한 위 자료구조들은 원소들을 순차적으로 실행할 때의 참조 지역성이 뛰어나다.
    • 이웃한 원소의 참조들이 메모리에 연속해서 저장되어 있다는 것이다.
    • 하지만 참조들이 가리키는 실제 객체가 메모리에서 서로 떨어져 있으면 참조 지역성이 나빠진다.
    • 참조 지역성이 낮으면 스레드는 데이터가 주 메모리에서 캐시 메모리로 전송되어 오기를 기다리며 대부분 시간을 멍하니 보내게 된다.
    • 참조 지역성은 다량의 데이터를 처리하는 벌크 연산을 병렬화 할 때 아주 중요한 요소다.
    • 참조 지역성이 뛰어난 자료구조는 기본 타입의 배열이다.
    • 데이터 자체가 메모리에 연속해서 저장되기 때문이다.

 

 

  • 스트림 파이프라인 종단 연산 중 병렬화에 가장 적합한 것은 축소(reduction)이다.
    • 축소는 파이프라인에서 만들어진 모든 원소를 하나로 합치는 작업이다.
    • 반면 가변 축소를 수행하는 Stream의 collect 메소드는 컬렉션들을 합치는 부담이 있어 병렬화에 적합하지 않다.

 

  • 직접 구현한 Stream, Iterable, Collection이 병렬화의 이점을 제대로 누리게 하고 싶다면 spliterator 메소드를 반드시 재정의하고 결과 스트림의 병렬화 성능을 강도 높게 테스트하라

 

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

 

  • 스트림 병렬화는 오직 성능 최적화 수단임을 기억해야 한다.

 

  • 다른 최적화와 마찬가지로 변경 전후로 반드시 성능을 테스트하여 병렬화를 사용할 가치가 있는지 확인해야 한다.

+ Recent posts