Kotlin

sequence

kakaroo 2022. 3. 27. 15:56
반응형

article logo

 

컬렉션 API 중, map이나 filter 같은 함수는 결과 컬렉션을 즉시 생성합니다.

이것은 즉, 컬렉션 함수를 연쇄하면 매 단계마다 중간 계산 결과를 새로운 컬렉션에 임시로 저장하고 있다는 말입니다.

반면에, 시퀀스(sequence)를 사용하면 중간 임시 컬렉션을 사용하지 않고도 컬렉션 연산을 연쇄할 수 있습니다.

 

sequences 의 여러 단계 처리는 전체 단계가 처리된 결과가 요구됬을 때에 실제 연산이 일어나며 느리게(나중에) 처리됩니다. (executed lazily)

동작 수행의 순서 또한 다릅니다. Sequence 은 각각 하나의 element 에 대해 모든 단계를 수행합니다.

Iterable 은 전체 collection 에 대해 각 단계의 수행을 완료하고 다음 단계로 넘어갑니다.

따라서, sequence 는 중간 단계의 결과에 대한 처리를 피할 수 있게 해주며, collection 전체 처리에 대한 수행 성능이 향상됩니다.

하지만 크기가 작은 collection 이나 단순한 연산 동작에 대해서는 오히려 불필요한 오버헤드가 생길 수 있습니다.

그러므로 어느 경우에 Sequence  Iterable 이 나을지 적절한 선택을 해야 합니다.

 

 

asSequence()

ListSet 같은 Iterable object 를 이미 가지고 있다면 asSequence() 함수를 통해 sequence 를 생성합니다.

data class Person (val name: String, val age:Int)

val person = ArrayList<Person>()
person.add(Person("김바다", 35))
person.add(Person("김하늘", 38))
person.add(Person("김소금", 24))
person.add(Person("박강남", 38))
person.add(Person("최무선", 65))
person.add(Person("이우진", 28))
person.add(Person("이용규", 34))
person.add(Person("박곰탕", 66))

println(person.asSequence()
    .map{it.name}
    .filter{it.startsWith("김")}
    .toList())

//[김바다, 김하늘, 김소금]

 

전체 연산을 수행하면서 중간 결과를 저장하는 컬렉션이 생기지 않기 때문에, 원소가 아무리 많은 경우에도 성능이 눈에 띄게 좋아집니다! 

위 경우는 컬렉션만 만들지 않을 뿐 수행하는 횟수는 같습니다.

 

아래의 예를 하나 더 들어보겠습니다.

리스트의 값을 꺼내 2배 한 뒤, 그 값이 3으로 나눠 떨어지는 첫 번째 값을 찾고자 합니다.

시퀀스를 사용하지 않는다면, 100부터 10000000까지 2배를 한 컬렉션을 먼저 생성하고,

다시 그 값을 하나씩 꺼내 3의 배수인 값으로 컬렉션을 생성한 뒤, 제일 첫번째 값을 꺼내옵니다.

 

시퀀스를 사용하게 되면 6번 수행만에 원하는 결과를 가져올 수 있습니다.

(100..10000000).asSequence()
    .map{ println("map: $it"); it*2}
    .filter{ println("filter: $it"); it % 3 == 0}
    .first()

//    map: 100
//    filter: 200
//    map: 101
//    filter: 202
//    map: 102
//    filter: 204

 

generateSequence()

이 함수는 인자를 2개 받는데, seed 인수롤 초기값으로 받고 다음 인자로 next function인 람다함수로 파라미터를 받아 sequence list를 생성해서 리턴하게 됩니다.

val numbers = generateSequence(0) { it + 1 }
val numbersTo100 = numbers.takeWhile { it <= 100 }
println(numbersTo100.sum()) //모든 연산은 "sum()"이 호출될 때 수행된다. (최종 연산)
반응형

'Kotlin' 카테고리의 다른 글

inline 함수  (0) 2022.04.01
enum class, sealed class  (0) 2022.03.31
collection  (0) 2022.03.27
reduce, fold  (0) 2022.03.26
lateinit, lazy  (0) 2022.03.26