References: Do it! 코틀린 프로그래밍

코틀린에서의 인라인 함수에 대해 알아봅니다.

 

 

1. 인라인함수란?

 

일반 함수가 호출되면 분기가 일어납니다. 따라서 내부적으로 기존 작업 내용을 저장했다가 다시 돌아올 때 복구하는 작업이 필요하며 이러한 작업에 CPU와 메모리에 비용이 발생합니다.

 

인라인 함수는 일반 함수와 달리 인라인 함수의 모든 내용을 함수가 호출되는 곳에 복사합니다.

예를들면

 

fun main(...) {
    ...
    sum()
    ...
    sum()
}
fun sum(){
    //Sum process
}

 

위와 같은 일반함수는 sum()이 호출될 때마다 분기가 일어나 총 2번의 분기가 발생합니다.

만약 sum()이 아래와 같이 인라인 함수로 선언되어 있다면 

inline fun sum(){
    //Sum process
}

 

함수가 실행될 때 sum()함수로 이동되는게 아닌 함수 내용이 복사되어 다음과 같이 수행됩니다.

 

fun main(...) {
    ...
    //Sum process
    ...
    //Sum process
}

 

 

2. 인라인 함수의 제한.

 

인라인 함수의 경우 모든 함수 내용을 복사해 넣기 때문에 함수의 코드가 길면 성능 문제가 발생할 수 있습니다.

다음 예시를 통해 인라인 함수를 제한하는 법을 알아보겠습니다.

 

inline fun sum(out1: ()->Unit, out2: ()->Unit)

 

위의 함수가 인라인으로 실행되면 내부의 두 람다함수도 인라인으로 들어가게됩니다. 

이런함수를 여러번 호출하게되면 코드의 양이 많아지는 문제가 발생합니다.

이런 문제를 해결하기 위해 일부 람다식은 인라인으로 실행되지 않게 하기 위해 noinline 키워드를 사용합니다.

 

inline fun sum(out1: ()->Unit, noinline out2: ()->Unit)

 

 

3. 비지역 반환

 

코틀린에서 익명함수를 종료하기 위해서 return을 사용할 수 있습니다.

그럼 인라인함수에서 사용한 람다식은 어떻게 빠져나올수 있을까요?

인라인 함수내부의 람다식에서는 return문을 사용할 수 있습니다.

다음 예시를 살펴봅시다.

 

inline fun inlineFun(a: Int, out: (Int)->Unit) {
    println("Before calling out()")
    out(a)
    println("After calling out()")
}
fun main(){
    inlineFun(1) {
        println("First call $it")
        return
    }
}

 

위의 예시에서 out(a)는 인라인되어 대체됩니다. 따라서 return을 포함하게 됩니다. 

이로 인해 out(a)에서 return이 포함되버려 println("After calling out()")는 실행되지 않게 됩니다.

이렇게 람다함수에서 return을 만났지만 의도하지 않은 바깥함수인 inlineFun()가 반환 처리되는 것을 비지역 반환이라고 합니다.

 

이런 의도치 않은 비지역 반환을 금지시키기 위해 다음과 같이 코드를 수정합니다.

 

inline fun inlineFun(a: Int, crossinline out: (Int)->Unit) {
    println("Before calling out()")
    nestedFun{ out(a) }
    println("After calling out()")
}
fun nestedFun(body: ()->Unit){
    body()
}
fun main(){
    inlineFun(1) {
        println("First call $it")
        //crossinline에 의해 더이상 return을 사용할 수 없습니다.
    }
}

 

crossinline 은 비지역 반환을 금지해야하는 람다식에 사용됩니다. 

결과를 출력시켜보면 정상적으로 After calling out()이 출력되는걸 확인할 수 있습니다.

 

 

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 16. 꼬리 재귀 함수  (0) 2019.08.23
[Kotlin] 15. 확장함수와 중위함수  (0) 2019.08.23
[Kotlin] 13. 익명함수  (0) 2019.08.23
[Kotlin] 12. 함수 호출 방법  (0) 2019.08.22
[Kotlin] 11. 람다식  (0) 2019.08.22

+ Recent posts