본문 바로가기
프로그래밍 놀이터/Kotlin, Coroutine

[Effective Kotlin] Item 49: Prefer Sequence for big collections with more than one processing step

by 돼지왕 왕돼지 2022. 6. 10.
반응형

이 글은 Effective Java 를 완독하고, Kotlin 을 상용으로 사용하는 개발자 입장에서
Effective Kotlin 글 중 새로운 내용, remind 할 필요 있는 부분, 핵심 내용 등만 추려 정리한 내용입니다.

 

#
Iterable 과 Sequence 를 동일한 것으로 보기 쉽다.
하지만 Sequence 는 lazy 하게 작동하며, terminal operation 을 만나면 작동한다.
반면 Iterable 은 중간과정에서 collection 을 계속 만들어낸다.

 

#
sequence 를 사용함으로써 갖는 장점은 아래와 같다.

  1. 자연적인 순서를 보장한다.
  2. 최소한의 작업을 한다.
  3. 무제한이 가능하다.
  4. 매번 collection 을 만들지 않는다.

 

 

Order is important

#
sequence 는 한 개의 element 가 아래 따라오는 모든 operation 을 돌고,
그 다음 element 가 같은 과정을 거치는 식으로 작동한다.
이를 'element-by-element' 또는 'lazy order' 라 부른다.
반면 iterable 에서는 모든 element 에 대해 첫번째 operation 을 적용해서 collection 을 만들고, 그 collection 기준으로 다음번 operation 을 수행하는 과정을 거친다.

 

#
sequence 는 compiler 최적화 관점에서도 더 유리하다.

 

 

Sequences do the minimal number of operations

#
결과 중 첫 10개의 element 만 사용하게 된다면 element-by-element 로 수행하는 sequence 가 최적이다.
first, find, take, any, all, none 등이 sequence 를 사용하기 좋은 operation 들이다.

 

 

Sequences can be infinite

#
sequence 를 만드는 일반적인 방법은 'generateSequence' 또는 'sequence' 를 사용하는 것이다.

generateSequence(1) { it + 1 }
	.map{ it * 2 }
	.take(10)
	.forEach { print("$it, ") }
// 2, 4, 6, 8, 10, 12, 14, 16, 18, 20

 

#
sequence 는 suspending function 으로 yield 함수를 통해 값을 발행해준다. 그리고 값을 필요로 하지 않을 때는 정지한 상태로 있는다.

val fibonacci = sequence{
	yield(1)
	var current = 1
	var prev = 1
	while(true){
		yield(current)
		val temp = prev
		prev = current
		current += temp
	}
}
print(fibonacci.take(10).toList())

 

#
infinite sequence 를 사용할 때는 무한 작업이 되지 않도록 조심해야 한다.
예를 들어 any 를 사용했다고 해도, infinite 값들 모두 그 조건을 충족할 수 없는 경우 무한작업이 된다.
따라서 take 등으로 갯수 조정을 해주는 것이 좋다.

 

 

Sequences do not create collections at every processing step

#
파일 등을 읽을 때 sequence 를 쓰면 좋다.

File("sample.csv").useLines { lines: Sequence ->
	// ...
}

 

#
one operation 에 대해서는 sequence 를 쓰지 않는 것이 유리하지만,
일반적으로 more than one operation & large collection 에 대해서는 sequence 가 유리하다.

 

 

What aren't sequences faster?

#
sorted 같은 operation 의 경우 결국 모든 값이 준비되어야 하므로 sequence 의 강점이 많지 않다.

 

 

What about Java stream?

#
Java 8 stream 도 lazy 하다. Kotlin sequence 와의 차이는 아래와 같다.

  1. Kotlin sequence 가 더 많은 operation function 을 제공한다.
  2. Java stream 은 parallel 함수를 이용해 병렬처리 가능하다.
  3. Kotlin sequence 는 Kotlin/JVM, Kotlin/JS 등 관련 모든 곳에서 활용 가능하다.

parallel mode 를 사용하는 것이 아니라면, Kotlin sequence 가 더 유용하다고 말할 수 있다.

 

 

Kotlin Sequence debugging

#
Java Stream 과 Kotlin Sequence 는 각각 plugin 으로 debugger 를 제공한다.
Kotlin Sequence Debugger 는 Kotlin plugin 에 통합되어 있다.

 

Summary

 

 

 

반응형

댓글