Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- etf
- 백준
- 현금흐름표
- S&P500
- 자바
- 그리디 알고리즘
- StringBuffer
- 인플레이션
- XLF
- object
- 접근제어자
- 금리인상
- 배당성장
- 알고리즘
- 프로그래머스
- 기업분석
- 미국주식
- mco
- 잉여현금흐름
- 주린이
- 오버라이딩
- Java
- 객체지향
- FCF
- 금리인하
- 주식
- 무디스
- javascript
- 제태크
- 다형성
Archives
- Today
- Total
오늘의하루
Java Stream이란? feat. 메모리 로드, 병렬 처리, 연산 흐름 본문
Stream의 특징
스트림(Stream)은 Java에서 일련의 데이터를 함수형 연산을 통해 효율적으로 처리할 수 있는 메커니즘입니다.
기본적으로 스트림은 지연 평가를 사용하여 연산을 효율적으로 처리합니다.
이를 통해 필요할 때만 연산을 실행하고 중간 연산 결과를 최적화할 수 있습니다.
병렬 처리를 원할 경우, parallel() or parallelStream()를 사용하여 스트림을 병렬 처리 모드로 전환할 수 있습니다.
- 병렬 Stream이 모든 상황에서 성능 향상을 보장하지 않습니다.
이렇게 하면 멀티 코어 CPU를 활용하여 대량의 데이터를 빠르게 처리할 수 있고, 병렬 처리된 각 부분의 결과를 최종적으로 합치는 과정을 거칩니다.
스트림의 이러한 특성 덕분에 Java에서는 복잡한 데이터 처리 작업을 보다 간편하게 처리할 수 있으며, 성능도 향상할 수 있습니다.
병렬처리 시 주의 사항
- 병렬 처리 시 여러 스레드가 나누어져 연산을 진행하기 때문에 연산이 끝나는 순서를 알 수 없어서 순서 보장이 되지 않는다.
- 병렬 처리 시 여러 스레드가 동시에 접근하기 때문에 공유 자원에 대한 동기화 문제를 고려해야 한다.
- 데이터가 작고 간단한 연산에 사용할 경우 오히려 성능에 악영향을 끼친다.
Stream의 연산 과정
Stream의 처리 과정은 생성 > 가공(N) > 최종 연산의 구조로 이루어져 있습니다.
- 생성:
- 생성은 데이터 집합을 Stream으로 변환하는 과정으로, 최초 1번 수행됩니다.
- 이때 데이터는 메모리에 로드되지 않으며, 어떤 데이터가 메모리에 로드될지는 가공 단계에서 결정됩니다.
- 가공:
- 가공은 Stream으로 변환된 데이터 집합을 원하는 형태로 가공하는 것이며, 가공의 입력값과 결괏값은 모두 Stream 타입이므로 메서드 체이닝이 가능해집니다.
- 가공의 가장 중요한 특징은 지연 평가(Lazy Evaluation)입니다.
- 실제 Stream 사용 시 생성 후 가공 연산이 진행되지 않고, 최종 연산이 호출된 후 가공 연산이 진행됨을 의미하며 이때 첫 번째 가공 연산에서 필요한 데이터만 메모리에 로드됩니다.
- 최종 연산:
- 최종 연산은 가공이 끝난 후 결과물을 얻기 위해 최초 1번 수행됩니다.
- 최종 연산이 수행되면 Stream이 닫히기 때문에 이후 또다시 가공이나 최종 연산을 수행할 수 없습니다.
가공 단계 최적화
- Fiilter와 Map 사용 시 Filter 연산을 먼저 진행하게 되면 Map 연산에서 불필요한 연산을 피할 수 있습니다.
Stream 예시
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamEx {
public static void main(String args[]) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 일반 Stream
List<Integer> streamTest = numbers.stream().filter(ele -> ele % 2 == 0).map(ele -> ele * ele).collect(Collectors.toList());
System.out.println(streamTest);
}
}
- StreamTest의 경우 병렬처리가 되어 있지 않은 Stream입니다.
- 병렬 처리를 하려면 stream(). parallel()... 또는 parallelStream()... 이렇게 작성해야 합니다.
- 지연 평가로 인해 최종 연산 collect() 호출 후 중간 연산이 실행됩니다.
- Stream은 numbers의 요소를 하나씩 메모리에 로드하여 처리합니다.
- 병렬 처리하는 경우 각 스레드마다 사용하는 요소들이 메모리에 로드됩니다.
- 간단한 연산을 병렬로 처리 시 오버헤드로 인해 성능에 악영향을 미칠 수 있습니다.
'JAVA' 카테고리의 다른 글
CPU-bound와 I/O-bound 작업의 병렬 처리 (0) | 2024.05.23 |
---|---|
[Test Code] Mockito를 활용한 랜덤 값 포함 함수 유닛 테스트 (0) | 2024.05.23 |
AOP - java.lang.ClassCastException (0) | 2024.02.23 |
Type safety: Unchecked cast from ~ (0) | 2024.02.16 |
(객체 지향 설계) 순수 자바로 DIP 원칙 지키기 (0) | 2023.08.19 |
Comments