Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

밤빵's 개발일지

[TIL]20241129 Inline 함수와 Reified 키워드 본문

Kotlin

[TIL]20241129 Inline 함수와 Reified 키워드

최밤빵 2024. 11. 29. 01:09

코틀린을 공부하면서 람다와 함수 사용에서의 성능 문제에 대해 접하게 되었다. 특히, 람다를 무명 클래스로 컴파일하는 코틀린의 특성 때문에 성능 저하의 가능성이 있다는 점을 알게 되면서 람다의 효율성을 개선하기 위해 사용하는 inline 함수와 타입 보존을 위한 reified 키워드에 대해 학습하고, 각각의 개념과 동작 원리를 정리해야 할 필요를 느꼈다.....! 

 

Inline 함수

코틀린에서 람다는 기본적으로 무명 클래스로 변환된다. 무명 클래스란 특정 시점에 객체로 만들어지는 임시 클래스를 의미하고, 이 과정에서 메모리를 추가로 사용하게 된다. 그렇다고 모든 람다가 매번 새로운 클래스를 생성하는 것은 아니고, 람다가 특정 변수를 포획할 때(클로저 사용 시) 새로운 무명 클래스 객체가 생성된다. 이런 과정이 동일한 작업을 반복 수행하는 경우 성능을 저하시킬 수 있다. 이런 경우를 해결하기 위해 코틀린은 inline 키워드를 제공한다. inline 키워드를 함수에 붙이면, 컴파일러는 해당 함수를 호출하는 모든 위치에 함수의 본문을 그대로 삽입한다. 함수 호출에 따르는 오버헤드와 무명 클래스 생성의 비용을 줄일 수 있어서, 성능이 향상된다.

 

일반 함수와 Inline 함수 비교해보기

fun withoutInline(block: () -> Unit) {
    println("함수 시작")
    block()
    println("함수 끝")
}

inline fun withInline(block: () -> Unit) {
    println("함수 시작")
    block()
    println("함수 끝")
}

fun main() {
    withoutInline {
        println("일반 함수 호출")
    }

    withInline {
        println("Inline 함수 호출")
    }
}

withoutInline 함수는 일반 함수로, 호출 시 람다 블록이 무명 클래스로 변환된다. 반면, withInline 함수는 inline 키워드를 사용하여 컴파일러가 함수 호출을 실제 함수 본문으로 대체한다. 따라서 withInline 함수의 경우, 함수 호출의 오버헤드를 줄이고 람다 생성 비용을 절감할 수 있다. 다만 inline 키워드를 사용하는 데도 제한이 있다. 람다를 다른 변수에 저장하거나, 함수가 호출된 이후에 사용하려는 경우에는 해당 람다를 인라이닝할 수 없고 무명 클래스를 생성해야 한다. 이런 상황에서는 inline의 장점을 활용할 수 없기 때문에 주의가 필요하다..!


Reified 키워드

reified 키워드는 inline 함수와 함께 사용되는 키워드로, 제네릭 타입을 런타임에 보존하기 위해 사용된다. 코틀린에서는 일반적으로 제네릭 타입은 컴파일 시점에 지워지기 때문에, 런타임에는 타입 정보를 알 수 없다(타입 소거). 하지만 reified 키워드를 사용하면 제네릭 타입 정보를 런타임에도 사용할 수 있게 된다. reified 키워드는 반드시 inline 함수에만 사용할 수 있다. 이유는 reified 타입 정보를 런타임에 보존하려면, 컴파일 타임에 함수의 본문을 인라인으로 대체해야 하기 때문!

 

Reified 키워드 사용해보기

inline fun <reified T> printTypeName(value: T) {
    println("타입: ${T::class.simpleName}")
}

fun main() {
    printTypeName(123) // 출력: 타입: Int
    printTypeName("Hello") // 출력: 타입: String
}

→ printTypeName 함수는 제네릭 타입 T를 받고 있고, reified 키워드를 통해 타입 정보를 런타임에 보존한다. 이를 통해 T::class.simpleName을 사용하여 타입 이름을 출력할 수 있다. 만약 reified 키워드를 사용하지 않았다면, 제네릭 타입 T는 컴파일 시점에 지워지기 때문에 런타임에 타입 정보를 알 수 없었을 것이다.


느낀 점과 학습 내용 정리

  • Inline 함수는 함수 호출 오버헤드를 줄이고, 람다의 무명 클래스 생성을 방지하여 성능을 향상시킬 수 있는 유용한 도구이다. 특히 람다가 반복적으로 호출되는 경우 성능 이점을 극대화할 수 있다.
  • Reified 키워드는 제네릭 타입을 런타임에도 사용할 수 있게 해준다. 타입 소거 문제를 해결하고, 타입 정보를 다루는 기능을 더 쉽게 구현할 수 있다.
  • 이번 학습을 통해, 코틀린의 inlinereified 키워드를 적절히 사용하는 것이 코드의 성능과 유지보수성에 큰 영향을 미칠 수 있다는 것을 알게 되었다.