inline 함수와 crossinLine 키워드
inline fun과 fun의 차이는 뭘까?
바로 컴파일 타임에 어떻게 처리되는지에 따라 차이가 있다.
fun함수는 호출 시점에 함수의 코드를 실행하며, 이 과정에서 호출 스택에 새로운 함수 프레임이 추가된다.
inline fun 는 컴파일러가 함수의 본문 코드를 실제 호출 위치에 직접 삽입하므로, 함수 호출에 따른 오버헤드가 없다.
오버헤드란?
함수 호출에 따른 오버헤드(overhead)란 함수를 호출하는데 필요한 추가적인 처리 시간이나 메모리 사용량을 말한다.
함수를 호출하면, 컴퓨터는 메모리의 특정 영역인 스택에 함수의 매개변수, 지역 변수, 반환 주소 등을 저장한다. 이러한 정보는 함수가 종료될 때 까지 유지되며, 함수가 반환되면 스택에서 제거된다. 이런 과정은 CPU 시간과 메모리를 소비하므로, 이를 함수 호출에 따른 오버헤드라고 한다.
또한, 함수를 호출할 때마다 프로그램의 실행 흐름이 함수 내부로 이동하고, 함수가 종료되면 원래의 위치로 돌아와야 하는데, 이러한 컨텍스트 스위칭(context switching)도 추가적인 시간을 소비하게된다.
inline fun 는 특히 람다 함수와 사용할 때 유용하다. 일반적으로 람다 함수는 함수 객체를 생성하고 사용하므로 추가적인 메모리와 시간이 소요된다. 그러나 inline fun 에서 람다를 사용하면, 컴파일러는 람다 코드를 함수 호출 위치에 직접 삽입하므로 이러한 오버헤드를 줄일 수 있다.
단점
매번
inline fun으로 함수를 선언하게 되면 어떻게 될까?
함수의 본문 코드를 호출 위치에 복사하기 때문에, 여러번 호출하는 함수가 있으면 코드의 크기가 그만큼 크게 증가할 수 있으며 이는 앱의 성능과 메모리 사용량에 영향을 주게 된다.
결론
inline fun는 주로 작은 함수나 람다를 매개변수로 취하는 고차 함수에서 사용하는 것이 바람직하다고 볼 수 있다.
CrossinLine은 뭘까?
crossinline은 Kotlin에서 제공하는 키워드로, inline 함수 내에서 사용되는 람다 함수에 대해 비-로컬 반환(non-local returns)을 금지하는 역할을 한다.
일반적으로 inline 함수 내부에서 람다를 사용할 때, 람다 내부에서 return 키워드를 사용하면 이는 비-로컬 반환을 의미한다. 즉, return은 람다 뿐만 아니라 람다를 포함하고 있는 inline 함수까지 종료시킨다.
이런 비-로컬 반환은 때때로 원치 않는 동작을 초래할 수 있다. 예를 들어, 람다를 실행하는 함수가 루프나 상위 함수 등의 중요한 실행 흐름을 제어하는 경우, 람다에서의 return이 이러한 제어 흐름을 방해할 수 있다.
이런 경우 crossinline 키워드를 사용하면, 해당 람다 함수 내에서 return 키워드를 사용하는 것을 금지하게 된다. 따라서 crossinline이 붙은 람다 함수 내에서는 로컬 반환만 가능하게 되며, 이는 해당 람다 함수 자체만 종료시키고 함수의 나머지 부분은 계속 실행하게 된다.
이렇게 crossinline 키워드를 사용하면 inline 함수와 람다 함수를 더 안전하게 사용할 수 있게 도와줄 수 있다.
결론
crossinLine은 함수 내부에서 비-로컬 반환을 할 수 없게 만든다.


