병렬처리(1) - Stream API 를 이용해 간단히 병렬화 하기.
JAVA8 을 공부하는 있는 책인 [JAVA8 in Action] 에서 언급되었던 내용 중 한 가지는 "공짜로 병렬성을 얻을 수 있다"는 것이었습니다. Collection 군의 데이터를 새로 추가된 API 인 Stream 의 형태를 parallel 관련 keyword 를 사용하여, 선언형 프로그래밍을 작성하면 병렬처리가 된다는 것이었죠.
아래는 병렬처리를 수행하는 간단한 예제입니다.
1 2 3 4 5 6 7 8 9 10 | // Collection 클래스 군의 parallelStream 사용. List<Integer> boxedDataList = IntStream.of(dataSet).mapToObj(Integer::new).collect(Collectors.toList()); boxedDataList.parallelStream().reduce(Integer::sum).ifPresent(System.out::println); // 순차스트림 (IntStream) 을 병렬스트림으로 변 IntStream.of(dataSet).boxed().parallel().reduce(Integer::sum).ifPresent(System.out::println); // 출력 결과 // 499500 // 499500 | cs |
위의 예제를 보면 정말 간단하다는 것을 알 수 있습니다. (Too Simple!!)
병렬 keyword 를 제외한 중간, 최종 연산 방법이 생각이 안나면, 이 곳을 참고하세요.
간단히 리뷰를 해보면,
1번 선언에서는 일반적으로 Collection 에서 스트림을 구하는 것 대신에 parallelStream 키워드를 통해 병렬스트림으로 변경한 후, 처리를 하고 있습니다.
2번 선언에서는 이미 순차스트림인 상태를 parallel 중간연산을 사용하여 병렬스트림으로 변경시켰습니다.
단순히 병렬스트림으로 변경하는 것만으로 병렬처리를 할 수 있으니, 책에서 소개한 것과 같이 공짜로 병렬성을 얻었다는 말이 뻥은 아니라는 것을 알 수 있습니다. ㅡㅡ^
즉 병렬처리를 하기 위해 생각해봐야할 고민인
사용할 스레드 개수, 경쟁상태(race condition), 계산된 결과들의 동기화 등이 추상화되었습니다.
parallel 관련 키워드 메소드를 사용하여 순차스트림을 병렬스트림으로 변경했들이,
병렬스트림을 순차스트림으로 변경할 수도 있습니다. sequencial 키워드로 말이죠. :-)
하지만, 이러한 중간연산(parallel 과 sequencial)을 아래와 같이 특정 중간연산의 제어를 하겠다는 목적으로 여러번 사용하는 것은 부질 없습니다. ㅡㅡ^
1 2 3 4 5 6 | IntStream.of(dataSet).boxed() .parallel() .filter(n -> n % 2 == 0) .map(n -> n + 2) .sequential() .collect(Collectors.reducing(Integer::sum)).ifPresent(System.out::println); | cs |
최종적으로 선택된 sequential 만 적용되며, 위 연산은 순차상태로 계산됩니다.
하지만, 이러한 병렬처리가 무조건 성능을 끌어다 줄까요?
이 이야기는 다음 포스팅에서...
|
'개발이야기 > 함수형 프로그래밍' 카테고리의 다른 글
병렬처리(3) - Spliterator (0) | 2017.02.16 |
---|---|
병렬처리(2) - 병렬스트림 잘 알고 사용하기! (0) | 2017.02.15 |
Collectors! 데이터를 수집해보자. (0) | 2017.02.02 |
Stream API 활용편5 (숫자형 스트림, 스트림 생산) (0) | 2017.01.25 |
Stream API 활용편4 (리듀싱) (0) | 2017.01.23 |