여러 요소를 병렬로 변환하여 성능 향상
suspend fun <T, R> List<T>.mapAsync(
transformation: suspend (T) -> R
): List<R> = coroutineScope {
[email protected] { async { transformation(it) } } // 각 요소를 병렬 작업으로 시작
.awaitAll() // 모든 작업 완료 대기
}
// 학생 정보 병렬 조회
suspend fun getBestStudent(
semester: String,
repo: StudentsRepository
): Student =
repo.getStudentIds(semester)
.mapAsync { repo.getStudent(it) }
.maxBy { it.result }
// 사용자 코스 병렬 처리
suspend fun getCourses(user: User): List<UserCourse> =
courseRepository.getAllCourses()
.mapAsync { composeUserCourse(user, it) }
.filterNot { courseShouldBeHidden(user, it) }
.sortedBy { it.state.ordinal }
순차 처리 → 병렬 처리로 성능 대폭 향상
suspend 함수도 한 번만 실행하고 결과 재사용
// ❌ 컴파일 에러
val connection by lazy { makeConnection() }
fun <T> suspendLazy(
initializer: suspend () -> T
): suspend () -> T {
var mutex = Mutex() // 동시성 제어
var holder: Any? = NOT_SET // 초기화 여부 확인
return {
if (holder !== NOT_SET) holder as T // 이미 초기화됨
else mutex.withLock { // 락으로 안전하게
if (holder === NOT_SET) holder = initializer()
holder as T
}
}
}
suspend fun makeConnection(): String {
println("Creating connection")
delay(1000)
return "Connection"
}
val getConnection = suspendLazy { makeConnection() }
suspend fun main() {
println(getConnection()) // "Creating connection" → "Connection" (1초 후)
println(getConnection()) // "Connection" (즉시)
println(getConnection()) // "Connection" (즉시)
}