병렬 스트림?

자바 7부터 고성능 병렬 분해(Parallel decom-position) 프레임워크인 포크-조인을 추가했다. 자바 8부터는 병렬 파이프라인을 병렬 실행할 수 있는 스트림을 지원한다. 이를 통해 동시성 프로그램을 작성하기 쉬워지고 있다. 그러나 남용하면 안된다.

보통 병렬 스트림을 사용하면 무조건 더 빨라질거라고 생각하지만 그렇지 않다. 예를 들어 스트림을 병렬으로 나누느라 리소스를 더 가져간다거나 혹은 실패할 수도 있다. 또한 중간 연산으로 limit을 사용하면 병렬 연산의 의미가 퇴색된다. limit을 사용하면 CPU 코어가 남으면 원소를 더 처리하고 제한 개수 이후 결과는 버려도 된다고 가정한다. 이는 계산 하나하나 연산이 오래걸리는 작업이라면 버릴 결과를 위해서 연산을 하는 것과 같다.

따라서 리소스, 병렬로 나눴을 때 효용성을 고려해야 한다. 스트림 소스가 ArrayList, HashMap, HashSet, ConcurrentHashMap의 인스턴스거나 배열 int 범위, long 범위일 경우 효과가 좋다. 이들의 공통점은 순차적으로 실행할 때 참조 지역성이 뛰어다는 것이다.

또한 종단 연산 중 reduction에 적합하다. min, max, count, sum, anyMatch, allMatch, noneMatch 같은 연산 말이다. 가변 축소하는 collect는 그다지 병렬에 적합하지 않다.

정리하면 스트림 병렬에는 주의해야 한다. 항상 행복한 결과가 있지는 않다. 성능이 나빠지거나 예상치 못한 동작을 발생할 수 있다. 또한 병렬화에 드는 추가 비용을 상쇄할 정도의 결과가 나오지 않으면 단일 스트림이 낫다.