Closed 102092 closed 3 years ago
위 글에서 이 아이템의 결론을 알 수 있군요
Stream의 parallel에 대해 여러가지 논쟁과 토론이 많다. 주로 내용들은 Deadlock 상황이나 Thread가 의도하지 않게 많이 만들어 질 수 있다라는 내용이다. 주로 원인은 ForkJoinPool을 사용하면서 발생하는 문제이다. 여러 블로그나 문서를 참조하면 다음과 같은 parallel 사용 시 주의 사항이 많이 언급되고 있다.
아이템48과 다른 도서 Practical 모던 자바을 참고하면서 느낀점은 기존의 Concurrent API, 포크/조인 프레임워크를 이해하고 제대로 활용한 다음에 스트림 병렬화를 시도해야할 듯 합니다.
데이터 소스가 Stream.iterate거나 중간 연산으로 limit를 쓰면 파이프라인 병렬화로는 성능 개선을 기대할 수 없다. 파이프라인 병렬화는 limit를 다룰 때 CPU 코어가 남는다면 원소를 몇 개 더 처리한 후 제한된 개수 이후의 결과를 버려도 아무런 해가 없다고 가정한다.
본문 내용 중 궁금한 것이 있어서 질문남깁니다. limit 을 쓰면 왜 병렬화로는 성능 개선을 기대할 수 없는 것인가요?
limit()는 요소의 순서에 의존하는 연산이라 성능이 더욱 떨어진다고 합니다. 오라클 공식문서에 따르면 stream
For parallel streams, relaxing the ordering constraint can sometimes enable more efficient execution. Certain aggregate operations, such as filtering duplicates (distinct()) or grouped reductions (Collectors.groupingBy()) can be implemented more efficiently if ordering of elements is not relevant. Similarly, operations that are intrinsically tied to encounter order, such as limit(), may require buffering to ensure proper ordering, undermining the benefit of parallelism. In cases where the stream has an encounter order, but the user does not particularly care about that encounter order, explicitly de-ordering the stream with unordered() may improve parallel performance for some stateful or terminal operations. However, most stream pipelines, such as the "sum of weight of blocks" example above, still parallelize efficiently even under ordering constraints.
번역: 병렬 스트림의 경우 순서 제한을 완화하면 때때로 더 효율적인 실행이 가능할 수 있습니다. 중복 필터링 (distinct()) 또는 그룹화 된 축소 (Collectors.groupingBy())와 같은 특정 집계 작업은 요소 순서가 적절하지 않은 경우보다 효율적으로 구현할 수 있습니다. 마찬가지로 limit ()와 같이 발생 순서에 본질적으로 연결된 작업은 적절한 순서를 보장하기 위해 버퍼링이 필요할 수 있으며, 이는 병렬 처리의 이점을 약화시킵니다. 스트림에 발생 순서가 있지만 사용자가 그 발생 순서에 대해 특별히 신경 쓰지 않는 경우, unordered()를 사용하여 스트림의 순서를 명시적으로 취소하면 일부 상태 저장 또는 터미널 작업에 대한 병렬 성능이 향상 될 수 있습니다. 그러나 위의 "블록 가중치 합계"예제와 같은 대부분의 스트림 파이프 라인은 순서 제약 조건에서도 여전히 효율적으로 병렬화됩니다.
unordered()나 findAny()를 먼저 호출하고, limit()을 호출하는 법이 더욱 빨라질 가능성이 있습니다.
약간 주제에서 벗어난 내용인 것 같긴 한데, 한번 읽어보면 좋을 것 같아요
https://www.popit.kr/java8-stream%EC%9D%98-parallel-%EC%B2%98%EB%A6%AC/