오늘은 코루틴을 메인 스레드에서 실행해보고 그 결과에 대해 생각해보는 시간을 가져보았다.
어떤 작업을 시킬까
이번에는 단순한 연산을 시킬 예정이다. 아주 많이
팩토리얼(Factorial) 계산을 시켜보겠다.
코드를 보자.
fun calculateFactorial(number: Int): BigInteger {
var factorial = BigInteger.ONE
for (i in 1 .. number) {
factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
}
return factorial
}
여기서 BigInteger를 사용했는데 간단히 말하면
Integer형으로 계산할 때 오버플로우가 날만한 범위까지도 계산이 가능한 클래스이다.
viewModelScope에서 실행하기 전 의문점 해소하기
현재 듣고 있는 강의에서 viewModelScope에 launch 코루틴 빌더를 가장 많이 사용하고 있다.
그런데, 코드를 작성하다보니 의문이 들었다.
CoroutineScope(Dispatchers.IO).launch {
// ...
}
이런 식으로 내가 코루틴 스코프를 따로 생성할 때 전달하는 Dispatcher 종류가 있다.
당연히 그 중에는 Main도 있다.
그런데 viewModelScope에서 launch 코루틴 빌더를 사용하면 Dispatcher를 주지 않는다.
찾아보면 viewModelScope는 기본적으로 Dispatchers.Main.immediate를 가지고 있다.
(immediate에 대해서는 나중에 천천히 알아보도록 하자)
이제 정말 실행해보기
아까 작성해둔 함수를 viewModelScope에서 실행해볼텐데
해당 함수가 실행되는데 소요되는 시간이 궁금해졌다.
여기서 사용해본 함수는 measureTimeMillis이다.
fun performCalculationOnMain(factorial: Int) {
viewModelScope.launch {
var result = BigInteger.ONE
val computationDuration = measureTimeMillis {
result = calculateFactorial(factorial)
}
var resultInString = ""
val conversionDuration = measureTimeMillis {
resultInString = result.toString()
}
println("calculation: $computationDuration, conversion: $conversionDuration")
}
}
이 결과는 어떻게 되었을까?
50000 정도의 정수를 입력 값으로 전달하면 계산이 대략 1초 정도, 문자열 변환이 대략 2초 정도 소요된다.
만약 수가 더 커진다면 어떻게 될까?
점점 ANR과 가까워지게 된다.
(ANR: Application Not Responding)
모든 작업을 메인 스레드에서 실행하고 있으니 다른 UI 상호작용이 불가능한데
해당 이벤트를 5초 이상 처리하지 못하면 ANR이 발생하기 때문이다.
따라서, 무작정 코루틴을 메인 스레드에서 실행하는 것은 옳지 않다.
'Language > Kotlin' 카테고리의 다른 글
Coroutines Dispatcher 알아보기 (2) | 2024.09.13 |
---|---|
CoroutineContext와 CoroutineScope 알아보기 (1) | 2024.09.04 |
Extract retry logic into higher order function from previous Coroutine (0) | 2024.08.25 |
Implement Coroutines Retry (1) | 2024.06.05 |
Implement Coroutines Timeout (0) | 2024.05.29 |