Advanced Kotlin – Inline Functions (1) – Basic

다음글: Advanced Kotlin – Inline Function (2) – Local Return


어떤 코드라고 해도 성능 이슈(Performance Impact Issue)는 있길 마련이다. 그러면 Kotlin은 이 성능 이슈를 줄이기 위해 어떠한 기능을 가지고 있을까?

앞으로 소개할 Inline Functions 가 그에 대한 해답이 될 수 있다.

Inline Functions 란?

람다 파라미터(lambda parameter) 를 가지고 있는 Functions에서 작동하는 기능으로 불필요한 코드를 제거하고 실행한 메소드 안으로 복사-붙여넣기 하는 기능이다.

function에 inline 라는 키워드를 앞에 붙임으로써 활성화 할 수 있다. 겉으로는 별 차이가 없어보이지만 실제로 JVM Bytecode로 볼 때 차이가 있다.

아래와 같은 코드를 봐보자.

inline fun operation(op: () -> Unit) {
        println("Before calling op()")
        op()
        println("After calling op()")
}

operation이란 메소드는 op 란 람다 파라미터를 가지고 있고, 전후에 println을 호출한다. 실행은 operation { println("This is the actual op function") } 로 된다.

이 메소드를 컴파일 해서 보면,

protected void onCreate(@Nullable Bundle savedInstanceState) {
        String var3 = "Before calling op()";
        System.out.println(var3);
        String var4 = "This is the actual op function";
        System.out.println(var4);
        var3 = "After calling op()";
        System.out.println(var3);
}

public final void operation(@NotNull Function0 op) {
        Intrinsics.checkParameterIsNotNull(op, "op");
        String var3 = "Before calling op()";
        System.out.println(var3);
        op.invoke();
        var3 = "After calling op()";
        System.out.println(var3);
}

onCreate 에 operation을 실행하게 하고 컴파일한 결과이다. 보이다싶이 operation 에 있는 내용들이 onCreate 안으로 흡수되었다. invoke, checkParameterIsNotNull등 불필요한 코드를 제거하고 말이다.

그렇다면 inline와 inline를 하지 않은 바이트코드는 어떤 차이를 보일까.

왼쪽이 inline를 하지 않은것, 오른쪽이 inline 된 것이다. 결과적으로 JVM에서 실행할 코드가 줄어들었다.

이걸로 보면 별 차이가 없는 것 처럼 보이지만 라이브러리 처럼 실행 속도를 중시해야하는 코드의 경우에는 거대한 차이가 있을 것이다.

만일 메소드에 람다 파라미터가 두개 이상 있고, 어떤 파라미터는 inline를 하고 싶지 않을 경우 noinline 키워드를 붙여줘서 inline 되지 않게 할 수 있다. inline fun operation(op: () -> Unit, noinline opp: () -> Unit)

그렇다면, inline functions의 제약 조건을 살펴보자.

제약 조건

오직 람다 파라미터만 가능

앞에서도 말했다싶이 inline는 람다 파라미터를 가지고 있는 메소드만 가능하다. 만일 람다 파라미터를 가지고 있지 않는 메소드에서 inline를 붙이게 되면 컴파일러는 경고를 호출한다.

이 메소드를 inline 함으로서 발생되리라 추측되는 성능 이슈는 비효율적일 수 있다. inline는 람다 파라미터에서 제대로 효과를 발휘한다.

파라미터에 대한 참조 불가

즉, invoke 이외의 기능을 사용할 수 없다.

결론

inline는 어떻게 보면 자바의 바이트코드로 인한 성능 이슈를 최적화하기 위해 나온 것과 가깝다.

물론, 위에 적혀져 있는 것 빼고 inline는 local returns에도 활용할 수 있다. 이는 다음 글에서 살펴볼 예정이다.

Inline Functions에 대한 문서: https://kotlinlang.org/docs/reference/inline-functions.html