Kotlin의 Sequence는 지연 시퀀스로, 큰 데이터 집합이나 잠재적으로 무한한 데이터 집합을 효율적으로 작업할 수 있게 해줍니다. Sequence에 대한 연산(map, filter 등)은 즉시 수행되지 않고, 대신 작업의 체인이 구축되고 결과는 필요할 때(터미널 연산 예: toList)만 계산됩니다.
중요한 이유:
코드 예제:
val numbers = generateSequence(1) { it + 1 } .filter { it % 2 == 0 } .map { it * it } .take(5) .toList() println(numbers) // [4, 16, 36, 64, 100]
이 예에서는 시퀀스의 첫 5개 요소만 실제로 계산되며, 잠재적으로 무한한 시퀀스입니다.
시퀀스를 사용할 때:
일반 Kotlin 컬렉션에서
map및filter와 같은 연산자가 지연된다고 보장할 수 있습니까? 왜 그렇습니까?
답변: 아니오, Kotlin의 표준 컬렉션 연산(List.map, List.filter 등)은 엄격히 즉시 수행됩니다. 각 연산은 중간 컬렉션을 생성하며 모든 요소를 즉시 처리합니다. 지연성은 Sequence를 사용할 때만 지원됩니다.
예제:
val data = listOf(1,2,3,4) val mapped = data.map { println("Mapping $it"); it * 2 } // 모든 값을 즉시 인쇄합니다.
이야기
대규모 CSV 파일(쓰기 시 최대 기가바이트)을 처리하는 프로젝트에서, 컬렉션은 처음에 List에 완전히 로드되고, 이후 chain map/filter가 적용되었습니다. 애플리케이션은 OutOfMemory 오류가 발생하였고, 문제는 List를 Sequence로 교체함으로써 해결되었습니다. Sequence의 map/filter는 거대한 중간 리스트를 생성하지 않았습니다.
이야기
여러 DB에서 보고서를 집계하는 백엔드 서비스는 처음에 검색 결과를 List에 축적한 후 필터링했습니다: 요청이 느려지고 GC 지연이 관찰되었습니다. 생성기 + Sequence로의 교체는 데이터 집계를 즉시 가능하게 하여 지연 시간을 줄였습니다.
이야기
Java에서 마이그레이션된 프로젝트는 큰 데이터 스트림을 처리할 때 map, filter와 같은 Kotlin의 표준 확장을 사용했으며, Java 8의 스트림처럼 코드가 지연된다고 생각했습니다. 이 오류는 메모리 누수와 프로덕션에서의 갑작스러운 다운타임을 초래했습니다.