병렬화(prallel())을 통해 성능 향상을 기대할 수 없는 경우
데이터 소스: Stream.iterate()
중간 연산: limit()
종단 연산: collect()
// 병렬 스트림을 사용해 처음 20개의 "메르센 소수"를 생성하는 프로그램 (291쪽 코드 48-1의 병렬화 버전)
// 주의: 병렬화의 영향으로 프로그램이 종료하지 않는다.
public class ParallelMersennePrimes {
public static void main(String[] args) {
primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
**.parallel() // 스트림 병렬화**
.filter(mersenne -> mersenne.isProbablePrime(50))
.limit(20)
.forEach(System.out::println);
}
static Stream<BigInteger> primes() {
return Stream.iterate(TWO, BigInteger::nextProbablePrime);
}
}
===
병렬화의 효과가 좋은 경우
public class ParallelPrimeCounting {
// 코드 48-3 소수 계산 스트림 파이프라인 - 병렬화 버전 (295쪽)
static long pi(long n) {
return LongStream.rangeClosed(2, n)
**.parallel()**
.mapToObj(BigInteger::valueOf)
.filter(i -> i.isProbablePrime(50))
.count();
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
System.out.println(start);
System.out.println(pi(10_000_000));
System.out.println(System.currentTimeMillis() - start);
}
}
단지 parallel() 함수가 splietrator 함수를 사용하구 있구나 정도
Spliterator == Splitting + Iterator
• 병렬 처리 지원: Spliterator는 데이터 소스를 여러 부분으로 나누어 병렬로 처리할 수 있도록 설계되었습니다. 이를통해 멀티코어 프로세서에서 성능을 크게 향상시킬 수 있다.
• 지연 바인딩: Spliterator는 실제로 필요할 때까지 데이터 소스에 바인딩을 지연시킬 수 있다. 이는 효율성을 높이고메모리 오버헤드를 줄이는 데 도움이 된다.
• 성능 향상: 데이터 소스를 분할하고 병렬로 처리함으로써 대용량 데이터 세트의 대량 작업 성능을 향상시킬 수 있다.
• 유연성: Spliterator는 다양한 데이터 구조(컬렉션, 배열, 사용자 정의 데이터 소스 등)를 순회하고 분할하는 유연한 방법을 제공한다.
• 함수형 프로그래밍: Spliterator는 람다 표현식 및 스트림 API와 같은 Java의 함수형 프로그래밍 기능과 잘 작동하여 간결하고 읽기 쉬운 코드를 작성할 수 있다.
• 특성 제공: Spliterator는 데이터 소스의 속성(예: ORDERED, DISTINCT, SORTED 등)을 설명하는 특성을 제공하여 최적화 및 효율적인 처리가 가능하다.
• Spliterator 주요 API: tryAdvance(), forEachRemaining(), trySplit(), characteristics(), estimateSize()
// 순회 하는 Spliterator
public class SpliteratorExample {
public static void main(String[] args) {
List<String> list = Arrays.asList("apple", "banana", "cherry", "date");
Spliterator<String> spliterator = list.spliterator();
System.out.println("spliterator.tryAdvance:");
spliterator.tryAdvance(System.out::println); // apple
System.out.println("spliterator.forEachRemaining:");
spliterator.forEachRemaining(System.out::println); // banana ... date
}
}
===
// 쪼개기
// 각 spliterator 에 어떤 객체가 들어갈지는 알 수 없다.
public class SpliteratorTrySplitExample {
public static void main(String[] args) {
List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "elderberry", "fig", "grape");
Spliterator<String> spliterator1 = list.spliterator();
Spliterator<String> spliterator2 = spliterator1.trySplit();
System.out.println("Spliterator 1:");
spliterator1.forEachRemaining(System.out::println);
System.out.println("Spliterator 2:");
if (spliterator2 != null) {
spliterator2.forEachRemaining(System.out::println);
}
}
}
===
// 비트 연산을 통한 효율적 계산 및 확인
public class SpliteratorCharacteristicsExample {
public static void main(String[] args) {
List<String> list = Arrays.asList("apple", "banana", "cherry", "date");
Spliterator<String> spliterator = list.spliterator();
// Check and print characteristics
int characteristics = spliterator.characteristics();
System.out.println("Characteristics: " + characteristics);
// System.out.println("Characteristics: " + Integer.toBinaryString(characteristics));
// Check if the Spliterator is ORDERED
if ((characteristics & Spliterator.ORDERED) != 0) {
System.out.println("Spliterator is ORDERED");
}
**// 이렇게 쓰는게 더 좋아보이기도 하고?**
if (spliterator.hasCharacteristics(Spliterator.ORDERED)) {
System.out.println("Spliterator is ORDERED");
}
// Check if the Spliterator is DISTINCT
if ((characteristics & Spliterator.DISTINCT) != 0) {
System.out.println("Spliterator is DISTINCT");
}
// Check if the Spliterator is SORTED
if ((characteristics & Spliterator.SORTED) != 0) {
System.out.println("Spliterator is SORTED");
}
// Check if the Spliterator is SIZED
if ((characteristics & Spliterator.SIZED) != 0) {
System.out.println("Spliterator is SIZED");
}
// Check if the Spliterator is NONNULL
if ((characteristics & Spliterator.NONNULL) != 0) {
System.out.println("Spliterator is NONNULL");
}
// Check if the Spliterator is IMMUTABLE
if ((characteristics & Spliterator.IMMUTABLE) != 0) {
System.out.println("Spliterator is IMMUTABLE");
}
// Check if the Spliterator is CONCURRENT
if ((characteristics & Spliterator.CONCURRENT) != 0) {
System.out.println("Spliterator is CONCURRENT");
}
// Check if the Spliterator is SUBSIZED
if ((characteristics & Spliterator.SUBSIZED) != 0) {
System.out.println("Spliterator is SUBSIZED");
}
}
}
무작위 수로 이뤄진 스트림 만들기