조슈아 블로크 님의 "Effective Java" 책을 정리한 포스팅 입니다.
1. 반환 타입으로는 스트림보다 컬렉션이 낫다
원소 시퀀스 반환시, 스트림 처리와 반복 처리 모두를 만족시키도록 노력하자
스트림은 반복을 지원하지 않음
- Iterable 확장 X
- 반복문에서 사용하기 어려움
- 그러나, Iterable이 정의한 추상 메서드를 모두 정의함
Collection이나 그 하위타입을 쓰자
- Iterable의 하위타입
- stream 메서드도 지원함
하위 타입 사용 시 주의점
- 메모리가 큰 시퀀스를 무작정 메모리에 올리면 안됨
예
멱집합 원소 배열
public class PowerSet {
public static final <E> Collection<Set<E>> of(Set<E> s) {
List<E> src = new ArrayList<>(s);
if (src.size() >= 30) throw new IllegalArgumentException("too many elements");
return new AbstractList<Set<E>>() {
@Override public int size() { return 1 << src.size(); }
@Override public boolean contains(Object o) {
return o instanceof Set && src.containsAll((Set) o);
}
@Override public Set<E> get(int idx) {
Set<E> result = new HashSet<>();
for (int i = 0; idx != 0; i++, idx >>= 1) {
if ((idx & 1) == 1) result.add(src.get(i));
}
return result;
}
}
}
}
- 멱집합을 구성하는 각 원소의 인덱스를 비트 벡터로 사용
- AbstractList를 이용하여 전용 컬렉션 구현하기
2. 스트림 병렬화는 주의해서 적용하라
parallel()
- 스트림 파이프라인을 병렬 실행할 수 있는 스트림 반환
- 여러 스레드에서 데이터를 처리하여 성능을 향상시킬 수 있음
주의사항
- 작은 데이터에 사용하면 오버헤드로 인해 오히려 성능이 저하될 수 있음
- 순서를 보장하지 않음
- 공유 상태 사용 주의
- CPU 코어를 활용하므로, 코어 수보다 병렬 작업이 크지 않아야 함
적합성 판단 기준
Spliterator
- 데이터 소스를 나누는 작업
- Stream이나 Iterable의 spliterator 메서드로 얻어올 수 있음
- 성능을 좌우하는 가장 큰 요소
데이터 소스
- 효율적인 소스
- 나누는 작업이 수월함
- ArrayList, HashMap, HashSet, ConcurrentHashMap
- int 스트림, long 스트림
- 배열
- 효율이 낮은 소스
- Stream.iterate와 같은 스트림
- limit를 사용 (순차적 처리 필요)
- 연결 리스트 (Random Access 필요)
참조 지역성
- 메모리 접근이 순차적으로 이루어질수록 캐시 효율이 높아져 성능이 좋아짐
- 다량의 데이터를 처리하는 벌크 연산에 중요
적합한 연산
- reduce 연산 시, 효과가 가장 좋음
안전 실패
- 스트림을 잘못 병렬화 하면, 성능이 나빠질 뿐만 아니라 잘못된 결과를 얻어올 수 있음
Random 처리
- 무작위 수들로 이뤄진 스트림을 병렬화 할 때, ThreadLocalRandom보단 SplittableRandom을 사용
예
소수 계산 스트림 파이프라인
LongStream.rangeClosed(2, n)
.mapToObj(BigInteger::valueOf)
.filter(i -> i.isProbablePrime(50))
.count();
'Java' 카테고리의 다른 글
[Effective Java] 8-2. 메서드 (0) | 2024.12.31 |
---|---|
[Effective Java] 8-1. 메서드 (2) | 2024.12.31 |
[Effective Java] 7-2. 람다와 스트림 (0) | 2024.12.31 |
[Effective Java] 7-1. 람다와 스트림 (1) | 2024.12.31 |
[Effective Java] 6-3. 열거 타입과 애노테이션 (0) | 2024.12.31 |