스터디에서 [알고리즘 + CS 스터디]를 진행하고 있다.
해당 스터디를 진행하면서 CS 관련 주제를 하나씩 정해서 학습한다.
스터디에서 정한 주제를 매 주 정리해보려고 한다.
오늘은 Stream에 대해서 정리를 한다.
목차
- Stream이란?
- Stream의 3단계 구조(생성 -> 중간 연산 -> 최종 연산)
- Stream의 특징
- Stream의 장단점
- Stream을 사용하면 성능은 좋은가?
Stream이란?
스트림은 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 값 요소
스트림은 컬렉션 반복을 멋지게 처리하는 기능
- 모던 자바 인 액션
스트림은 컬렉션의 요소를 하나씩 참조해 람다식으로 처리할 수 있는 반복자
- 이것이 자바다
다양한 데이터 소스를 표준화된 방법으로 다루기 위한 것
- 자바의 정석
유명한 저서에서 각각 조금씩 다르게 말하지만 쉽게 생각해보면 스트림은 반복 또는 연속된 다양한 데이터들을 표준화된 방법으로 처리할 수 있게 해주는 것이다.
- 기존 Colleciton 프레임워크의 List, Set, Map
- 배열 데이터
- File
위의 데이터를 처리하는 방법은 모두 다르다.
Stream을 사용하면 List, Set, Map, Array, File 데이터를 모두 Stream으로 바꿔서 표준화된 방법으로 처리가 가능하다.
위의 List, Array와 같이 Stream으로 변환된 소스들을 스트림의 중간 연산들과 최종 연산을 통해서 모두 같은 방법으로 데이터를 다룰 수 있다.
Stream의 3단계 구조 (생성 -> 중간 연산 -> 최종 연산)
스트림은 세 단계 걸쳐서 동작한다.
- 스트림의 생성(Stream) : 생성
- 스트림의 중간연산(filter, sorted, distinct, map 등) : 가공
- 중간 연산은 0 ~ N번 반복 가능
- 스트림의 최종연산(collect, forEach, count 등) : 소비
- 최종 연산은 0 ~ 1번 가능
소스 코드로 보면 다음과 같이 3단계에 걸쳐서 실행된다.
첫 번째로 number Stream이 생성된다.
두 번째 중간 연산은 filter() -> sorted() -> distinct()가 실행된다.
마지막 최종 연산인 count() 실행되고 Stream이 종료된다.
Stream의 특징
- 스트림은 외부 반복(HOW 중심)을 통해 작업하는 컬렉션과는 다르게 내부 반복(WHAT 중심)으로 작업을 수행한다.
- 스트림은 재사용이 가능한 컬렉션과 달리 한 번만 사용이 가능하다.
- Steam은 Iterator처럼 일회용이다. (필요하면 다시 생성)
- 최종 연산을 하고나면 소비된다.
- 스트림은 원본 데이터를 변경하지 않는다
- 스트림은 병렬 처리를 지원한다..
- 스트림은 지연(lazy) 연산을 통해 성능을 최적화한다
- 최종 연산 전까지 중간연산이 수행되지 않는다.
- 선언형 코드로 간결해져 가독성이 좋다.
여기서는 첫 번째 외부 반복과 내부 반복에 대해서만 알아본다.
먼저 외부 반복과 내부 반복에 의미에 대해서 생각을 해본다. 필자도 처음에는 내부 반복과 외부 반복의 차이에 대해서 명확하게 이해가 되지 않았다.
외부 반복은 사용자가 직접 for문을 반복하면서 HOW 중심으로 코드를 작성하고 있다.
내부 반복은 사용자가 직접 for문을 반복하지 않고 중간 연산자인 filter를 통해 Stream 내부적으로 처리하고 어떠한 작업을 하고 있는지 WHAT 중심으로 코드를 작성하고 있다.
Stream의 장단점
- 장점
- 내부 반복으로 WHAT 중심으로 작성되어 있어서 가독성이 좋다.
- 병렬 처리를 지원한다.
- 단점
- 소스 코드가 간결하게 체이닝 되어 있어서 디버깅이 어렵다.
- Stream은 최종 연산이 호출되고 나면 close 되기에 재사용이 불가능하다.
- Stream은 for - loop 방식보다 성능과 속도면에서 좋지 않다.
Stream을 사용하면 성능은 좋은가?
이펙티브 자바 공저자의 발표 자료 일부에서는 극단적인 예시로 for-loop와 Stream으로 성능 비교를 했다.
결과는 Stream이 for-loop보다 많이 느리다는 결과이다. 거래에 오차가 발생하지 않아야 하는 주식 매매와 같은 사이트에서는 Stream 사용을 고려해 봐야한다.
주식 매매 사이트와 같은 속도가 최우선 되지 않는 이외의 사이트에서는 Trade-off를 고려해서 사용해야 한다.
Stream의 사용이 단점만 있는 것은 당연히 아니다. 최근에는 유지보수에 투자하는 비용이 하드웨어 비용보다 높은 경우가 많다. 객체지향 5원칙 중 SRP(단일 책임 원칙)와 같은 한 메서드는 하나의 역할만 하게 하는 것처럼 개발 회사에 따라 코드의 품질과 가독성이 더 중요하다면 Stream을 사용하는 회사도 많을 것이다.
참고 링크
'Java' 카테고리의 다른 글
[CS] Java 8 Lambda (0) | 2022.07.27 |
---|