들어가기 전에
Java에서는 stream()
을 통해 collection 요소를 하나씩 참조하여 반복적인 작업을 할 수 있습니다.
Kotlin에는 Collections 자체에 filter()
, map()
등의 API를 제공하고 있어 stream()
없이도 collection 요소에 하나씩 참조가 가능합니다.
위 내용만 보면, Java에서 collection에 stream()
붙여서 사용하는 경우와 Kotlin에서 collection의 API를 호출하는 경우 동일하게 연산이 이루어질 것 같지만 서로 상이하게 연산을 진행합니다.
- Java의 stream: Lazy Evaluation
- Kotlin의 collection 기본 연산(iterable): Eager Evaluation
이번 포스팅에서는 Kotlin의 collection 연산을 Java의 stream처럼 lazy evaluation 할 수 있는 Sequences()
연산과 Kotlin Collection의 기본 연산인 Iterable()
에 대해 알아보고자 합니다.
Lazy Evaluation과 Eager Evaluation
Lazy Evaluation
listOf(1,3,5,7,2,4,6,8)
.asSequence()
.filter {
print("filter: $it\n")
it < 5
}
.map {
print("map: $it\n")
it * it
}
.toList()
// 호출 결과
filter: 1
map: 1
filter: 3
map: 3
filter: 5
filter: 7
filter: 2
map: 2
filter: 4
map: 4
filter: 6
filter: 8
- 필요하지 않은 연산은 하지 않는 것으로, 여러 collection API가 체이닝되어 있을 때 collection 각 요소별로 체이닝된 API를 돌면서 실제 사용할 API까지만 호출하는 것입니다.
- Lazy Evaluation은 연산을 바로 수행하지 않고 실제 사용되기 전까지 미룹니다. 위 경우와 같이 결과를 반환하는 종료 함수(예:
toList()
)가 없을 때에는 collection 연산을 수행하지 않습니다.
Eager Evaluation
listOf(1,3,5,7,2,4,6,8)
.filter {
print("filter: $it\n")
it < 5
}
.map {
print("map: $it\n")
it * it
}
.toList()
// 호출 결과
filter: 1
filter: 3
filter: 5
filter: 7
filter: 2
filter: 4
filter: 6
filter: 8
map: 1
map: 3
map: 2
map: 4
- 여러 collection API가 체이닝되어 있을 때 collection 원소들에 대해 API를 모두 호출한 후 다음 API를 호출하는 방식으로 진행합니다.
- Eager Evaluation은 Lazy Evaluation과 다르게 매 체이닝 함수를 수행할 때마다 결과 collection을 반환합니다.
Sequences를 항상 사용해야 할까?
Kotlin 문서의 Sequences 설명을 보면, 위와 같은 내용이 있습니다.
더보기
sequences는 각 연산의 즉각적인 결과를 만드는 것은 피하게 되어 체이닝 연산 시 성능 향상을 기대할 수 있습니다. 다만, lazy 연산은 작은 collections 연산이나 간단한 계산을 할 때에는 오히려 오버헤드가 추가될 수 있기 때문에 Sequence와 Iterable 중 더 나은 선택을 고민하며 사용해야 합니다.
예를 들어, 아래와 같이 여러 체이닝 연산을 통해 나온 결과물 중 일부(any()
또는 take()
등)를 반환하는 경우라면 Sequence를 사용하는게 이점이 있을 수 있지만, 결국 체이닝 연산 대상이 되는 모든 결과물을 반환해야 한다면 sequences 사용이 오히려 오버헤드가 클 수 있다는 생각이 듭니다.
체이닝 연산을 모두 통과한 대상 중 일부만 반환하는 경우
Sequences 연산을 사용해도 Iterable 사용시와 연산 횟수가 동일한 예시
참고 자료
'PROGRAMMING LANGUAGE > KOTLIN' 카테고리의 다른 글
[Kotlin Coroutine] 코루틴 빌더와 비동기 패턴의 이해 (0) | 2024.06.16 |
---|---|
[Kotlin Coroutine] 코루틴 기본 이해 & JVM에서의 async (0) | 2024.06.08 |
[Kotlin]enum class와 data class (0) | 2022.08.25 |
[Kotlin] 객체 (0) | 2022.08.25 |
[Kotlin] 널 가능성 (0) | 2022.08.12 |