코루틴과 버추얼스레드

김수호·2024년 12월 7일

코틀린

목록 보기
1/5

다들 코루틴이 좋다고 하던데 순수 코루틴을 사용한다면 얼마나 성능이 발생하는지 궁금했다.
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만번 실행하게 하였다.

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

2. 순수 코루틴

    @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

3. 버추얼스레드

    @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

4. 버추얼스레드 + 순수 코루틴(디스패쳐, i/o 최적화)사용x

    @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

결론

코루틴에 대해서 제대로 사용하지 못할경우 컨텍스트 스위칭이 빈번하게일어나 오히려 속도면에서 문제가 발생할 수 있다.

profile
정답을 모르지만 답을 찾는 법을 알고, 그 답을 찾아낼 것이다. 그럼 괜찮지 않은가? -크리스 가드너-

0개의 댓글