Skip to content

Latest commit

 

History

History
60 lines (40 loc) · 4.09 KB

48_스트림_병렬화는_주의해서_적용하라_김세윤.md

File metadata and controls

60 lines (40 loc) · 4.09 KB

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

동시성 프로그래밍

Untitled Untitled11

  • 자바는 동시성 프로그래밍을 항상 지원하려고 노력했습니다.
  • 처음부터 스레드, 동기화, wait/notify를 지원하였습니다.
  • 자바5부터는 동시성 컬렉션인 java.util.concurrent 라이브러리와 실행자(Executor) 프레임워크를 지원하였으며, 자바 7부터는 고성능 병렬 분해 프레임워크인 포크-조인 패키지를 추가했습니다.
  • 자바8부터는 스트림을 통해 병렬 실행할 수 있도록 지원하였습니다.
  • 이 처럼 자바는 동시성 프로그래밍을 꾸준히 지원하는데, 동시성 프로그래밍을 할 때는 안정성과 응답 가능 상태를 유지를 해야 한다.

스트림 병렬화의 문제점

  • 데이터 소스가 Stream.iterate거나 중간 연산으로 limit를 쓰면 파이프라인 병렬화로는 성능 개선을 기대할 수 없다.
    • limit을 다룰 때 CPU 코어가 남는다면 원소를 몇 개 더 처리한 후 제한된 개수 이후의 결과를 버려도 아무런 해가 없다고 가정한다.

스트림 파이프라인의 명세 규약

  • 스트림을 잘못 병렬화하면 (응답 불가를 포함해) 성능이 나빠질 뿐만 아니라 결과 자체가 잘못되거나 예상 못한 동작이 발생할 수있다.
  • Stream 명세는 이때 사용되는 함수 객체에 관한 엄중한 규약을 정의해놨습니다. 예를 들어 Stream reduce 연산에 건네지는 accumulator와 combiner 함수느 반드시 결합법칙을 만족하고, 간섭받지 않고, 상태를 갖지 않아야 한다.

스트림 병렬화를 적용하기 전에 고려 사항

  • 스트림 병렬화는 오직 성능 최적화 수단입니다.
  • 따라서 성능 테스트를 통해 가치가 있는지 확인해야 합니다.
  • 보통은 병렬 스트림 파이프라인도 공통의 포크-조인 풀에서 수행(같은 스레드 풀 사용)되므로 잘못된 파이프라인 하나가 다른 부분의 성능에까지 악영향을 미칠수 있다.

스트림 병렬화가 좋을 떄

  • 조건이 잘 갖춰지면 parallel 메서드 호출 하나로 거의 프로세서 코어 수에 비례하는 성능 향상을 만끽할 수 있다.
  • 스트림의 소스가 ArrayList, HashMap, HashSet, ConcurrentHashMap의 인스턴스나 배열, int, long 범위일 때 병렬화의 효과가 가장 좋다.
  • 그 이유는 아래와 같다.
    1. 자료구조들은 모두 데이터를 원하는 크기로 정확하고 손쉽게 나눌수 있어 일을 다수의 스레드에 분배하기 좋다.
      • 나누는 작업은 Spliterator가 담당하며, Spliterator 객체는 Stream 이나, Iterable의 spliterator 메소드로 얻어올수 있다.
    2. 순차적으로 실행할 떄 참조 지역성이 뛰어나다.
      • 참조 지역성이란 메모리에 연속으로 저장되어 있다는 의미
      • 가장 뛰어난 자료구조는 기본타입의 배열이다.

Random값 스트림 병렬화

ThreadLocalRandom

  • 단일 쓰레드에서 사용하기 위해 만들어졌다.

SplittableRandom

  • 무작위 수를 위한 스트림 병렳화를 위해 설계되었다.

Random

  • 모든 연산을 동기화 하기 떄문에 최악의 연산을 자랑한다.

결론

  • 스트림을 잘못 병렬화하면 (응답 불가를 포함해) 성능이 나빠질 뿐만 아니라 결과 자체가 잘못되거나 예상 못한 동작이 발생할 수있다.
  • 데이터 소스가 Stream.iterate거나 중간 연산으로 limit를 쓰면 파이프라인 병렬화로는 성능 개선을 기대할 수 없다.
  • 스트림의 소스가 ArrayList, HashMap, HashSet, ConcurrentHashMap의 인스턴스나 배열, int, long 범위일 때 병렬화의 효과가 가장 좋다.
  • 단순히 성능이 빨라질꺼라는 확신 없이 파이프라인 병렬화는 시도조차 하지 말아라.