#1 작업의 처리 방식
#1-1 가정
위와 같은 총 7개의 작업이 있다고 가정한다. 각 작업이 소요 시간은 5, 10, 15, 10, 20, 25, 5다.
#1-2 전통적인 방법
전통적인 방법은 선형적(Serial)으로 작업을 수행한다.
#1-3 전통적인 방법의 구현
import kotlinx.coroutines.*
data class Food(val name: String, val cookingTimeInSeconds: Long)
suspend fun cook(food: Food) {
delay(1000 * food.cookingTimeInSeconds)
println("${food.name} 완료")
}
fun main() {
val foods = arrayOf(
Food("국밥", 5),
Food("만두", 10),
Food("비빔밥", 15),
Food("햄버거", 10),
Food("치킨", 20),
Food("피자", 25),
Food("샌드위치", 5),
)
val startTime = System.currentTimeMillis()
runBlocking {
for (food in foods) {
cook(food)
}
}
val endTime = System.currentTimeMillis()
println("총 소요 시간: ${(endTime - startTime) / 1000.0}초")
}
/* 출력 결과
국밥 완료
만두 완료
비빔밥 완료
햄버거 완료
치킨 완료
피자 완료
샌드위치 완료
총 소요 시간: 90.168초
*/
전통적인 방식의 작업 처리를 코드로 나타내면 위와 같다.
#1-4 Parallel Decomposition
Parallel Decomposition은 문제를 작은 부분으로 나누어 동시에 처리한다. 7개의 작업 중 가장 오래 걸리는 작업이 곧 전체 소요 시간이 된다. 이 방법은 전체 작업의 시간을 단축시킨다. 다수의 CPU 코어를 효율적으로 활용해 대규모 문제를 나눠 해결한 것이다. 코틀린에서는 코루틴을 이용해 문제를 병렬로 나열함으로써 Parallel Decomposition을 구현할 수 있다.
#1-5 Parallel Decomposition의 구현
import kotlinx.coroutines.*
data class Food(val name: String, val cookingTimeInSeconds: Long)
suspend fun cook(food: Food) {
delay(1000 * food.cookingTimeInSeconds)
println("${food.name} 완료")
}
fun main() {
val foods = arrayOf(
Food("국밥", 5),
Food("만두", 10),
Food("비빔밥", 15),
Food("햄버거", 10),
Food("치킨", 20),
Food("피자", 25),
Food("샌드위치", 5),
)
val startTime = System.currentTimeMillis()
runBlocking {
val cookingJobs: ArrayList<Job> = ArrayList()
for (food in foods) {
cookingJobs.add(launch {
cook(food)
})
}
/* runBlocking의 특성 덕에 생략 가능. 설명 참조.
for(cookingJob in cookingJobs) {
cookingJob.join()
}
*/
}
val endTime = System.currentTimeMillis()
println("총 소요 시간: ${(endTime - startTime) / 1000.0}초")
}
/* 출력 결과
국밥 완료
샌드위치 완료
만두 완료
햄버거 완료
비빔밥 완료
치킨 완료
피자 완료
총 소요 시간: 25.104초
*/
Parallel Decomposition 방식의 작업 처리를 코드로 나타내면 위와 같다. 코루틴을 사용했다. for문의 반복 횟수만큼 코루틴이 병렬적으로 수행된다. 가장 큰 Food.cookingTimeInSeconds는 곧 모든 코루틴이 완료되는 시간이 된다. Job.join() 함수를 생략한 이유는 runBlocking 함수는 안에 있는 모든 코루틴이 끝나야 종료(이 링크의 #3-2 참조)되기 때문이다.
#2 요약
문제를 나눠서 푸는 건 누구나 할 수 있다. 하지만, 나눈 걸 병렬적으로 푼다면 얘기가 달라진다.
'깨알 개념 > Kotlin' 카테고리의 다른 글
[Kotlin] Coroutines - ViewModelScope (0) | 2024.02.20 |
---|---|
[Kotlin] Coroutines - 스레드 전환 (0) | 2024.02.19 |
[Kotlin] Coroutines - Structured Concurrency (0) | 2024.02.16 |
[Kotlin] Couroutine - 스레드(Thread)와 스레드 풀(Thread Pool) (0) | 2024.02.15 |
[Kotlin] Coroutines - suspend 키워드 (0) | 2024.02.14 |