Open ahah525 opened 1 year ago
변수에 접근하면 곧바로 연산을 시작하는 기법이다.
결과값이 필요할 때까지 계산을 늦추는 기법이다.
- 불필요한 연산은 수행하지 않기 때문에 대부분 성능이 좋다.
- 다만, 지연 연산을 위한 내부 준비 작업을 수행하기 때문에 무조건 효율적인 방식은 아니다.
파이프라인에서 복수의 스트림 연산을 하나의 연산 과정으로 병합하는 것이다.
- 루프 퓨전은 스트림 최적화 전략의 일종이다.
- 복수의 스트림 연산이 하나로 병합되면, 개별 스트림 요소에 접근하는 횟수가 최소화된다.
- 다만, 모든 스트림 연산에 대해 루프 퓨전이 적용되는 것은 아니다!
- 정렬 작업을 수행하기 위해서는 모든 요소가 필요하기 때문에 이러한 경우에는 루프 퓨전이 적용되지 않을 수 있다.
불필요한 연산을 수행하지 않음으로써 실행 속도를 높이는 기법이다.
- 스트림
limit
같은 연산을 활용해 스트림 일부 요소들에 대한 연산을 완전히 생략한다.
1~10 이 담긴 리스트에서 1) 6보다 작고 2) 짝수인 요소에 3) 10을 곱하여 4) 리스트로 만드는 예제다.
Eager Evaluation 방식의 반복문 예제
public static void t1() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int result = 0;
// 1번
List<Integer> list1 = new ArrayList<>();
for (Integer i : list) {
System.out.println(i + ": i < 6");
if(i < 6) {
list1.add(i);
}
}
// 2번
List<Integer> list2 = new ArrayList<>();
for (Integer i : list1) {
System.out.println(i + ": i % 2 == 0");
if(i % 2 == 0) {
list2.add(i);
}
}
// 3번
for (Integer i : list2) {
System.out.println(i + ": i *= 10");
i *= 10;
result = i;
break;
}
System.out.println(result);
}
⇒ 한 요소에 3번 접근한다. 1, 2, 3 과정이 구분되어 있다.
Lazy Evaluation 방식의 Stream 예제
public static void t2() {
final List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int result = list.stream()
.filter(i -> {
System.out.println(i + ": i < 6");
return i < 6;
})
.filter(i -> {
System.out.println(i + ": i % 2 == 0");
return i % 2 == 0;
})
.map(i -> {
System.out.println(i + ": i *= 10");
return i * 10;
})
.findFirst()
.get();
System.out.println("================");
System.out.println(result);
}
⇒ 한 요소에 1번 접근한다. 1, 2, 3 과정이 하나로 묶였다.
같은 동작을 하는 반복문
public static void t3() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int result = 0;
// 1번
for (Integer i : list) {
System.out.println(i + ": i < 6");
if(i<6) {
System.out.println(i + ": i % 2 == 0");
if(i%2==0) {
System.out.println(i + ": i *= 10");
i *= 10;
result = i;
break;
}
}
}
System.out.println("================");
System.out.println(result);
}
스트림
은 Lazy Evaluation
방식이다.Lazy Evaluation
의 최대 장점은 필요하지 않은 연산은 하지 않아도 된다는 점이다.지연 연산
을 기반으로 루프 퓨전
과 쇼트서킷
의 최적화 전략을 사용한다.중간 연산
은 즉시 실행되지 않고 최종 연산
이 호출될 때 뒤늦게 실행된다.
문제
p.151
에서“스트림의 게으른 특성 덕분에 몇 가지 최적화 효과를 얻을 수 있었다”
고 하며 최적화 기법으로 쇼트서킷과 루프퓨전을 언급하고 있다.스트림 특성인 게으름이 의미하는 바가 무엇인지 즉, lazy 방식이 eager 방식과 비교했을 때 무엇이 다른지를 이해하고 최적화 기법인 루프퓨전에 대해 알아보자.
참고로 쇼트서킷은 5장에서 자세히 설명한다고 나와있기 때문에 필요 시 예습 느낌으로 간단히 공부해보면 좋을 것 같아 질문에 포함시키진 않겠습니다.
관련 목차
참고자료