just_do_IT
[Java] Stream 이란? (장점, 단점, 사용 시기, 성능 Graph) 본문
여러 코드를 마주하다보면 Stream이 적지 않게 보이는 걸 알 수 있다. 특히 IO가 많이 발생하는 Client 부분의 코드에서 많이 보였다. 그냥 단순히 반복문을 간결하게 작성하는 기능 선에서만 대충 알고 있었는데, 이번 기회에 알아보기나 하자는 느낌으로 포스팅을 했다.
일단 Stream 을 왜 사용하는 지 부터 궁금했다. 여러 포스팅을 읽어보고 Java 공식 문서도 읽어보았다. 사용하는 이유가 정말 다양했지만 단편적으로 느낀 첫 번째 이유는 많은 양의 병렬 처리가 필요할 때 사용하면 좋다는 것이다. 코드 자체가 간결해져서 가독성이 향상되는 단편적인 장점도 있지만 아무래도 중, 장기적으로는 성능적인 면을 제대로 파악해야 적재적소에 Stream을 사용할 수 있을 것으로 판단했다. 많은 양의 병렬 처리가 필요할 때 사용하면 좋다는 건 적은 양의 단순 처리에 대해서는 오히려 포퍼먼스가 좋지 않은 것일까? Stream의 장점과 단점에 대해서 알아보자.
[1] Stream 장점 vs 단점
[결론]
장점
- 간결하고 가독성 높은 코드를 구현할 수 있고, 대규모의 반복 병렬 처리에 대해서 성능이 좋다.
단점
- Debuging 도 잘 안 되고, 일회성으로 소비되며 수행 시 마다 여러 method가 호출되므로 막 가져다 쓰면 성능이 오히려 저하된다.
1. 코드간결성 및 가독성
장점 : 반복문 없이 여러 Method 를 조합하여 가독성 높은 코드 작성이 가능하고, SQL 스타일의 선언형 방식이어서 가공 과정이 명확하다.
단점 : 직관적이지 않아 익숙하지 않은 개발자에게 학습 곡선이 가파를 수 있고, 람다 표현식이 복잡해지면 오히려 가독성이 떨어진다.
2. 재사용성
장점 : 변경 불가능한 Collection 조작 가능하고, 원본 데이터를 수정하지 않는다.
단점 : 선언된 Stream 은 한 번만 소비 가능하여, 재사용 시 새로운 Stream 을 생성해야 한다.
3. 성능
장점 : 병렬 처리(Parallel Stream)가 가능하다. parallelStream()을 사용하면 대용량 데이터 처리 시 성능 향상을 기대할 수 있다.
단점 : 비교적 작은 데이터 처리에는 method 호출 비용, 객체 생성 overhead 등의 성능 저하가 발생한다.
4. API 종류
장점 : map(), filter(), reduce(), sorted(), collect() 등 다양한 연산 제공한다.
단점 : 복잡한 요구사항에 있어 특정 연산이 필요한 경우 별도로 구현해야 할 수도 있다. 예를 들어 break 로 인한 조기 종료 등이다.
5. Debuging
장점 : .peek() 등을 이용해 중간 과정에 대해 확인은 할 수 있다.
단점 : 중간 부분의 연산을 파악 등의 Debuging이 타 반복문에 비해 복잡하고 어려움.
6. 메모리 관리
장점 : Lazy Evaluation(지연 연산)을 통해 필요한 경우에만 실행하여 메모리 사용 최적화가 가능하다.
단점 : 상황에 따라 불필요한 객체 생성이 증가되어 메모리 낭비가 발생할 수 있다.
위 정리가 정말 맞는 지 한 번 테스트를 해보자!
[2] Performance Test
공통 사항
- 각 조건을 총 50회 수행 후 결과의 평균값으로 graph 생성
- Y축 : 처리에 요청된 시간(ms)
- x축 : legend 참고
1번 조건 : 1,000 회 반복을 처리
![]() |
2번 조건 : 1,000,000 회 반복을 처리
![]() |
물론 여러 조건을 더 따지지 않고 단순하고 러프한 테스트지만 그래도 위 결과가 한눈에 잘 보인다.
최종 결론
- 대량 데이터를 한 번만 반복 처리할 때는 parallelStream()이 가장 유리하다.
- 순서를 보장해야 하면 Stream 또는 for문이 더 적합하다.
- 작은 데이터에서는 for문이 오히려 더 빠르다.
- 반복 사용해야 하면 for문이 좋고, 코드 가독성이 중요하면 Stream을 고려해야 한다.
이제 Stream을 언제 사용하는 지 대충 맛은 봤으니, 앞으로 Stream을 어떻게 사용하는 지 알아보자.
Java 8 version Stream 공식 문서 Link
Stream (Java Platform SE 8 )
A sequence of elements supporting sequential and parallel aggregate operations. The following example illustrates an aggregate operation using Stream and IntStream: int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight())
docs.oracle.com
Java 11 version Stream 공식 문서 Link
Stream (Java SE 11 & JDK 11 )
A sequence of elements supporting sequential and parallel aggregate operations. The following example illustrates an aggregate operation using Stream and IntStream: int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight())
docs.oracle.com
'초보 개발자의 스터디룸' 카테고리의 다른 글
[gRPC] Protobuf란? (0) | 2023.01.31 |
---|---|
[gRPC] gRPC 기초적인 추가 정보 2. 스트리밍 방식, 개발 순서 (0) | 2023.01.31 |
[gRPC] gRPC란? 1. 개요, 특징, 사례 (0) | 2023.01.31 |
[Logstash] 로그스태시란? 개요, 기능, 특징 (0) | 2023.01.09 |
[Elastic Search] 엘라스틱서치란? 3. 장/단점, ES vs RDBMS (0) | 2023.01.06 |