실제로 성능이 향상될지를 추정해보는 간단한 방법이 있다. 스트림 안의 원소 수와 원소당 수행되는 코드 줄 수를 곱해보자. 이 값이 최소 수십만은 되어야 성능 향상을 맛볼 수 있다.
동시성 프로그래밍을 할 때는 안전성(safety)과 응답 가능(liveness) 상태를 유지하기 위해 애써야 함
스트림 병렬화 효과 있을때/없을때
- 데이터 소스가
Stream.iterate
거나 중간 연산으로limit
을 쓰면 파이프라인 병렬화로는 성능 개선을 기대할 수 없다.
- 스트림의 소스가
ArrayList
,HashMap
,HashSet
,ConcurrentHashMap
의 인스턴스거나 배열, int 범위, long 범위일 때 병렬화의 효과가 가장 좋다. - 이 자료구조들은 모두 데이터를 원하는 크기로 정확하고 손쉽게 나눌 수 있어 일을 다수의 스레드에 분배하기에 좋다는 특징
- 또다른 중요한 공통점은 원소들을 순차적으로 실행할 때 locality of reference(참조 지역성)이 뛰어나다는 것(메모리에 이웃한 원소들이 연속해서 저장되어 있음)
- 참조 지역성이 낮으면 스레드는 데이터가 주 메모리에서 캐시 메모리로 전송되어 오기를 기다리며 대부분 시간을 멍하니 보내게 됨
- 따라서 참조 지역성은 다량의 데이터를 처리하는 벌크 연산을 병렬화할 때 아주 중요한 요소로 작용함.
- 나누는 작업은
Spliterator
가 담당
- 종단 연산 중 병렬화에 가장 적합한 것은 축소(reduction)다.
- 스트림을 잘못 병렬화하면 (응답 불가를 포함해) 성능이 나빠질 뿐만 아니라 결과 자체가 잘못되거나 예상 못한 동작이 발생할 수 있다.
- 실제로 성능이 향상될지를 추정해보는 간단한 방법이 있다. 스트림 안의 원소 수와 원소당 수행되는 코드 줄 수를 곱해보자. 이 값이 최소 수십만은 되어야 성능 향상을 맛볼 수 있다.
- 무작위 수들로 이뤄진 스트림을 병렬화하려거든 ThreadLocalRandom 보다는
SplittableRandom
인스턴스를 이용하자. SplittableRandom은 정확히 이럴 때 쓰고자 설계된 것이라 병렬화하면 성능이 선형으로 증가한다.
- 그냥
Random
은 모든 연산을 동기화하기 때문에 병렬 처리하면 최악의 성능을 보이게 됨