본문 바로가기
개발

코틀린(Kotlin) 에서 인라인 함수를 언제 사용해야 하나요?

by 얼굴값하는사람 2023. 12. 26.
반응형

코틀린의 인라인 함수를 사용하는법을 알아 보겠습니다.

 

 

질문 : 

인라인 함수가 성능을 향상시키고 생성된 코드를 증가시킬 수 있다는 것을 알고 있지만 언제 사용하는 것이 올바른지 잘 모르겠습니다.

lock(l) { foo() }

 

매개변수에 대한 함수 객체를 생성하고 호출을 생성하는 대신 컴파일러는 다음 코드를 내보낼 수 있습니다.

 

l.lock()
try {
  foo()
}
finally {
  l.unlock()
}

 

 

하지만 인라인이 아닌 함수에 대해 kotlin에서 생성한 함수 개체가 없다는 것을 발견했습니다.

/**non-inline function**/
fun lock(lock: Lock, block: () -> Unit) {
    lock.lock();
    try {
        block();
    } finally {
        lock.unlock();
    }
}
 
 

유형의 람다 () -> Unit(매개변수 없음, 반환 값 없음)를 사용하고 다음과 같이 실행하는 고차 함수를 생성한다고 가정해 보겠습니다.

fun nonInlined(block: () -> Unit) {
    println("before")
    block()
    println("after")
}

 

 

Java 용어로 이는 다음과 같이 번역됩니다(단순화!).

public void nonInlined(Function block) {
    System.out.println("before");
    block.invoke();
    System.out.println("after");
}

 

그리고 Kotlin에서 호출하면...

nonInlined {
    println("do something here")
}

 

 

내부적으로는 Function람다 내부에 코드를 래핑하는 인스턴스가 생성됩니다(이 역시 단순화되었습니다).

nonInlined(new Function() {
    @Override
    public void invoke() {
        System.out.println("do something here");
    }
});

 

따라서 기본적으로 이 함수를 호출하고 람다를 전달하면 항상 객체의 인스턴스가 생성됩니다.

 

inline키워드를 사용하는 경우:

inline fun inlined(block: () -> Unit) {
    println("before")
    block()
    println("after")
}

 

 

 

다음과 같이 호출하면:

inlined {
    println("do something here")
}

 

 

Function인스턴스가 생성되지 않습니다 . 대신 block인라인 함수 내부의 호출 관련 코드가 호출 사이트에 복사되므로 바이트코드에 다음과 같은 내용이 표시됩니다.

System.out.println("before");
System.out.println("do something here");
System.out.println("after");

 

이 경우 새 인스턴스가 생성되지 않습니다. ^^

 
 

 

반응형