다들 코루틴이 좋다고 하던데 순수 코루틴을 사용한다면 얼마나 성능이 발생하는지 궁금했다.
ps. 코틀린의 measureTimeMillis 기능을 이용해서 측정을 했다.
fun findPrime(limit: Int): Long {
var count = 0L
for (i in 2 until limit) {
if (isPrime(i)) {
count++
}
}
return count
}
fun isPrime(number: Int): Boolean {
for (i in 2 until sqrt(number.toDouble()).toInt() + 1) {
if (number % i == 0) return false
}
return true
}
위 코드를 1만번 실행하게 하였다.
@GetMapping("/test1")
fun testWithPlatformThreads() :String {
val threads = mutableListOf<Thread>()
val taskCount = 10_000
val time = measureTimeMillis {
repeat(taskCount) {
val thread = Thread {
findPrime(10_000)
}
threads.add(thread)
thread.start()
}
threads.forEach { it.join() }
}
return "PlatformThreads: $time ms"
}
측정결과 : 단위 ms
2722
2637
2376
@GetMapping("/test2")
suspend fun testWithCoroutines(): String = coroutineScope {
val taskCount = 10_000
val time = measureTimeMillis {
val jobs = List(taskCount) {
launch {
findPrime(10_000)
}
}
jobs.forEach { it.join() }
}
"Coroutines: $time ms"
}
측정결과 : 단위 ms
7333
7261
7160
@GetMapping("/test3")
fun testWithVirtualThreads(): String {
val executor = Executors.newVirtualThreadPerTaskExecutor()
val taskCount = 10_000
val time = measureTimeMillis {
val tasks = List(taskCount) {
executor.submit {
findPrime(10_000)
}
}
tasks.forEach { it.get() }
}
executor.shutdown()
return "Virtual Threads: $time ms"
}
측정결과 : 단위 ms
974
943
961
@GetMapping("/test4")
suspend fun testWithVirtualThreadsAndCoroutines(): String = coroutineScope {
val executor = Executors.newVirtualThreadPerTaskExecutor()
val taskCount = 10_000
val time = measureTimeMillis {
val jobs = List(taskCount) {
launch() {
executor.submit {
findPrime(10_000)
}.get()
}
}
jobs.forEach { it.join() }
}
executor.shutdown()
"Virtual Threads + Coroutines: $time ms"
}
측정결과 : 단위 ms
7432
7861
7689
코루틴에 대해서 제대로 사용하지 못할경우 컨텍스트 스위칭이 빈번하게일어나 오히려 속도면에서 문제가 발생할 수 있다.