Closed undeadtimo closed 3 months ago
parallel 메서드와 parallelStream 메서드가 단순히 스트림을 생성함과 동시에 병렬구조로 변환하는가, 이미 만들어진 스트림을 병렬구조로 변환하는가 순서의 차이로만 생각하고 있었는데요. 보다 구체적으로 조사하고 공유해주신 덕분에 예외적인 상황에 있어 반환 자료에 차이가 생길 수 있다는 것을 알게 되었습니다.
또, 병렬 처리의 비효율 가능성에 대해서도 스트림을 초기 비용에 대한 막연한 추측만 가지고 지나쳤던 부분이었는데, 연산 작업의 크기와 스트림의 크기 관계에 따라서도 차이가 생길 수 있다는 점을 탐구해주셔서 보다 확실히 이해할 수 있게 되었네요!
추가적인 탐구과 정리 감사합니다!
Based on : #182 by @yngbao97
저는 지금까지 Steam이라는 단어는 많이 보았지만, 그 개념에 대한 지식이 부족하여 코드를 이해하거나 다른 연관된 개념을 이해하는데 문제가 있었습니다.
그러나 Stream API에 대하여 정리해주셔서 Stream에 대한 개념을 확실히 잡을 수 있게 되었네요. 감사함을 전합니다.
특히 지연 평가에 대해 설명하는 부분에서 물이 흐르는 형태로 비유하여 지연 평가가 아닌 Stream의 데이터 처리 과정과 지연 평가인 Stream의 데이터 처리 과정을 쉽게 이해할 수 있었습니다.
마지막 병렬 처리 부분을 읽으면서 두 가지 의문이 생겼기에 제 나름 조사한 후 정리해보았습니다.
parallel()과 parallelStream() 모두 병렬처리를 구현한다면 왜 메서드가 두 개나 존재하는 것일까? 두 메서드에 대한 차이가 존재하는 것일까?
경우에 따라서는 병렬(parallel) 처리가 순차(sequence) 처리보다 느릴 수 있다는데, 그것은 어떤 경우를 말하는 것일까?
먼저 첫 번째 의문에 대해 조사한 것을 정리해보겠습니다.
parallel() 메서드는 Java 8 버전에 등장한 BaseStream의 것이며, parallelStream() 메서드는 Collection 인터페이스의 것입니다.
먼저 parallelStream 메서드는 Spliterator 인터페이스를 통해 병렬 Stream을 생성합니다.
Spilterator 객체는 trySplit() 메서드를 통해서 병렬처리가 가능하도록 데이터를 분할합니다.
다음으로 parallel() 메서드는 병렬 Stream을 생성하는 pararllelStream과 다르게 이미 만들어져있는 순차 Stream을 병렬 Stream으로 변환하는 기능을 수행합니다.
두 메서드는 각각 다음과 같이 사용할 수 있습니다.
위와 같은 클래스가 있다고 가정할 때,
위처럼 parallelStream() 메서드와 parallel 메서드를 사용할 수 있습니다.
위 경우, 만약 EffectiveJava와 SearchForMeaning에 같은 Book 객체들이 같은 순서로 들어가있다면 두 메서드는 같은 결과를 출력할 것입니다.
다만, parallelStream 메서드를 사용할 때 호출되는 Spliterator 인터페이스의 trySplit 메서드는 다뤄야 할 데이터 소스가 분할할 수 없을 정도로 작다고 판단하면 병렬 스트림 대신 순차 스트림을 반환합니다.
반면 parallel 메서드는 항상 병렬 스트림만을 반환하기에 이 부분에서 차이점을 갖는 것으로 확인할 수 있습니다.
다음으로 두 번째 의문인, 병렬 처리가 순차 처리보다 느린 경우에 대해 정리해보겠습니다.
스트림의 크기
연산 집약
쉽게 분할 가능한지
References:
[parallel 메서드와 parallelStream 메서드의 차이에 대한 글] https://www.baeldung.com/java-parallelstream-vs-stream-parallel
[병렬 처리와 순차 처리의 성능에 관한 글] https://blogs.oracle.com/javamagazine/post/java-parallel-streams-performance-benchmark