[kotlin] 코틀린에서의 CPU 바운드 작업과 I/O 바운드 작업 처리 차이

코틀린은 JVM 기반의 언어로, 자바와 마찬가지로 다양한 작업을 처리할 수 있습니다. 그 중에서도 CPU 바운드 작업과 I/O 바운드 작업을 처리하는 방식에는 차이가 있습니다.

CPU 바운드 작업

CPU 바운드 작업은 주로 계산이 많이 필요한 작업을 의미합니다. 예를 들면 소수를 판별하거나 행렬 연산 등이 있습니다. 이러한 작업은 단일 스레드에서 순차적으로 처리되는 것이 가장 효율적입니다. 따라서 코틀린에서도 단일 스레드를 사용하여 CPU 바운드 작업을 처리할 수 있습니다.

fun calculatePrimeNumbersInRange(start: Int, end: Int) {
    for (number in start..end) {
        if (isPrime(number)) {
            println(number)
        }
    }
}

fun isPrime(number: Int): Boolean {
    if (number <= 1) return false
    for (i in 2 until number) {
        if (number % i == 0) return false
    }
    return true
}

위의 예시 코드는 주어진 범위 내에서 소수를 찾아 출력하는 CPU 바운드 작업을 수행하는 코드입니다. 이렇게 작업을 단일 스레드로 처리하면 간단하고 성능상 이점이 있습니다.

I/O 바운드 작업

I/O 바운드 작업은 주로 디스크나 네트워크와 같은 입출력 작업을 의미합니다. 예를 들면 파일을 읽고 쓰기, 데이터베이스와 통신 등이 있습니다. 이러한 작업은 I/O 작업이 느리기 때문에 단일 스레드로 처리하면 성능이 저하될 수 있습니다.

코틀린에서는 I/O 바운드 작업을 비동기적으로 처리할 수 있습니다. Kotlin의 kotlinx.coroutines 패키지에서 제공하는 코루틴을 사용하면 I/O 작업이 블로킹되지 않고 더 효율적으로 작업을 처리할 수 있습니다.

import kotlinx.coroutines.*
import java.io.File

fun readFile(path: String) {
    val file = File(path)
    val content = runBlocking { file.readText() }
    println(content)
}

fun saveFile(path: String, content: String) {
    val file = File(path)
    runBlocking { file.writeText(content) }
}

fun main() {
    val path = "example.txt"
    
    // 파일 읽기
    GlobalScope.launch {
        readFile(path)
    }
    
    // 파일 저장
    GlobalScope.launch {
        saveFile(path, "Hello, World!")
    }
    
    // 대기
    Thread.sleep(1000)
}

위의 예시 코드는 파일을 비동기적으로 읽고 쓰는 I/O 바운드 작업을 수행하는 코드입니다. readFile 함수는 파일을 읽어서 내용을 출력하고, saveFile 함수는 파일에 내용을 씁니다. main 함수에서는 이러한 작업을 별도의 스레드에서 비동기적으로 실행하고, Thread.sleep(1000)을 통해 해당 작업이 완료될 때까지 대기합니다.

이렇게 비동기적으로 작업을 처리하면 I/O 바운드 작업의 성능이 향상됩니다.

정리