컬렉션 처리 단계 수를 제한하라 #
모든 컬렉션 처리 메서드는 비용이 발생한다.
" 표준 컬렉션 처리는 내부적으로 요소들을 활용해 반복문을 돌며, 계산을 위해 추가적인 컬렉션을 만들어 사용합니다. 시퀀스 처리도 시퀀스 전체를 wrap하는 객체가 만들어지며, 조작을 위해서 또 다른 추가적인 객체를 만들어 냅니다. 두 처리 모두 요소의 수가 많다면, 꽤 큰 비용이 들어갑니다. “
따라서 적절한 메서드를 활용해서, 컬렉션 처리 단계 수를 적절하게 제한하는 것이 좋다.
class Student(val name: String?)
// 작동은 합니다.
fun List<Student>.getNames(): List<String> = this
.map { it.name }
.filter { it != null }
.map { it!! }
// 더 좋습니다.
fun List<Student>.getNames(): List<String> = this
.map { it.name }
.filterNotNull()
// 가장 좋습니다.
fun List<Student>.getNames(): List<String> = this
.mapNotNull { it.name }
” 사실 컬렉션 처리와 관련해서 비효율적인 코드를 작성하는 이유는 그것이 필요 없다고 생각해서가 아니라, 어떤 메서드가 있는지 몰라서인 경우가 많습니다. “
공감된다.
쓸만한 함수 예시 #
- filterNotNull
- mapNotNull
- joinToString
- filterIsInstance
() - filter (책 확인)
- sortedWith(comparedBy())
- listOfNotNull(…)
- filterIndexed
요약 #
컬렉션 처리는 ‘전체 컬렉션에 대한 반복’, ‘중간 컬렉션 생성’이라는 비용이 발생한다.
적절한 컬렉션 처리 함수를 통해 처리 단계를 줄일 수 있다.
단계를 줄이자.