인라인 한번도 안 타본 1인
inline
키워드는 함수 호출을 인라이닝(inlining) 하도록 컴파일러에 지시하는 키워드로, 주로 람다나 고차 함수에서 성능을 최적화할 때 사용된다.
함수 호출 비용 감소
inline
키워드가 붙은 함수는 컴파일 시 함수 호출이 인라인되어 함수의 본문이 호출 지점에 직접 삽입된다. 따라서 함수 호출에 따른 오버헤드를 줄일 수 있다.
람다와 고차 함수에서 유용함
람다 표현식은 객체로 만들어지고, 메모리에 할당되며 함수 호출 시 람다 객체를 통해 호출이 이루어진다.
inline
키워드를 사용하면 람다도 인라인으로 삽입되어 불필요한 객체 생성이 줄어들고 성능이 향상된다.
따라서 고차 함수에 람다를 여러 개 넘기는 경우, inline을 사용해 성능 최적화를 할 수 있다.
Non-local returns
인라인 함수 내에서 람다를 사용할 때 return을 통해 호출한 지점에서 함수 전체를 종료할 수 있다. 일반적인 람다에서는 return이 로컬 리턴(local return)으로 작동하지만, inline
함수의 경우 함수 자체를 종료하는 non-local return이 가능하다.
inline fun inlineFunction(value: Int, block: (Int) -> Int): Int {
return block(value)
}
fun main() {
val result = inlineFunction(5) { it * it }
println(result) // 출력: 25
}
inline
함수에 전달되는 람다 중 특정 람다만 인라인하고 싶지 않은 경우, noinline
키워드를 사용할 수 있다.
inline fun performOperation(value: Int, block1: (Int) -> Int, noinline block2: (Int) -> Int): Int {
return block2(block1(value))
}
위처럼 noinline
키워드를 사용하면 block2 람다는 인라인되지 않는다.
inline
사용 시 주의할 점으로는
crossinline
키워드는 inline 함수의 파라미터로 전달된 람다가 비지역(non-local) return을 허용하지 않도록 할 때 사용된다.
일반적으로 inline 함수의 람다에서는 비지역 return을 사용할 수 있다.
비지역 return은 람다 내부에서 return을 호출하면, 해당 람다뿐 아니라 inline 함수를 호출한 곳에서 바로 리턴되도록 하는 것이다. 그러나 때로는 비지역 return을 허용하면 문제를 일으킬 수 있는 경우가 있어서, 이를 방지하기 위해 crossinline을 사용한다.
inline fun nocrossinlineFunction(block: () -> Unit) {
println("Before block")
block() // 이곳에서 람다 호출
println("After block")
}
fun main() {
myFunction {
println("Inside block")
return // 비지역 return이므로 main 함수로 리턴
}
println("Outside block") // 호출되지 않는다.
}
inline fun crossinlineFunction(crossinline block: () -> Unit) {
println("Before block")
action() // 비지역 return이 허용되지 않아 에러 발생
println("After block")
}
fun main() {
myFunction {
println("Inside block")
// return // 컴파일 오류 발생
}
println("Outside block")
}
위와 같이 crossinline
사용 시 람다에서 비지역 return을 호출할 수 없게 되어 오류가 발생해 비지역 return을 방지한다.
crossinline은 다음과 같은 경우에 유용합니다.
잘 사용한다면 성능 최적화 면에서 좋을 것 같다!