inline이 뭐하는 걸까?
우리가 코딩을 할 때 적극적으로 의식하지는 않지만, 함수를 호출하는건 어느정도 Overhead를 동반합니다. 보통은 현대 컴퓨터 성능이 워낙 좋고, 컴파일러가 최적화를 최대한 해 줘서 굳이 의식할 필요는 없습니다.
하지만 Kotlin에서는 함수가 일등시민이기 때문에, Parameter에 함수를 Argument로 넘기거나, 함수를 Return Type으로 가지는 함수가 있을 수 있습니다. 이는 자바에서는 FunctionN 객체를 만들거나 Closure를 사용할 경우 함수를 호출하는 방식으로 처리합니다. 이 경우 Kotlin에서 함수형 스타일의 코드가 성능에 어느정도 영향을 줄 수 있겠죠?
그럴때 inline을 쓰면 함수 호출 부분을 없애고 코드안에 함수 내용을 넣어 줍니다.
inline 될 경우 예시
이 Kotlin 코드는
inline fun add(num1: Int, num2: Int): Int {
return num1 + num2
}
fun main() {
val num1 = 1
val num2 = 1
val result = add(num1, num2)
}
이 Java 코드로 컴파일 됩니다.
public static final void main() {
int num1 = 1;
int num2 = 1;
int var = num1 + num2;
}
분명 함수를 호출했는데 inline 때문에 함수 호출 부분이 사라지고 라인 안으로 (inline) 된걸 볼 수 있습니다!
inline 함수의 parameter로 자동으로 inline된다
inline 함수는 (가능할 경우) 모든 parameter의 함수도 inline 시킵니다. 그래서
이 코드는
inline fun repeat(times: Int, exec: () -> Unit) {
for (i in 1 .. times) {
exec()
}
}
fun main() {
repeat(1) { println("Hello World") }
}
아래와 같이 exec도 inline 됩니다
public static final void main() {
int i$iv = 1;
while (true) {
System.out.println("Hello World");
if (i$iv == 2) { return; }
++i$iv;
}
}
noinline으로 inline 시키고 싶지 않은 parameter 지정하기
하지만 parameter는 inline 시키고 싶지 않을 수 있겠죠? 그런 경우에는 noinline을 써서 이 Parameter는 inline하지 말라고 알려줄 수 있습니다.
inline fun repeat(times: Int, noinline exec: () -> Unit) {
for (i in 1 .. times) {
exec()
}
}
inline되면 non-local return을 사용할 수 있다!
원래 Lambda는 fun keyword를 안 써서 return을 사용할 수 없습니다.
return의 역할 자체가 가장 가까운 fun keyword 함수에 return 값을 전해주는 것이기 때문입니다. 하지만 inline을 쓰면 함수가 없어지기 때문에 non-local return을 사용할 수 있습니다!
corssinline으로 non-local return 사용할 수 없게 하기
하지만 Lambda에서 non-local return을 사용하면 예상밖으로 inline 함수를 종료 시키는게 아니라, inline 함수를 호출한 함수를 종료시킵니다. 그래서 inline 함수라 하더라도 오류 방지나 헷갈려서 non-local return을 허용하고 싶지 않을 수 있습니다. 그럴 때는 crossinline을 사용하면 non-local return을 방지할 수 있습니다.
inline fun iterate(numbers: List<Int, crossinline exec: (Int) -> Unit) {}
'👨💻 프로그래밍 > Java, Kotlin, Spring' 카테고리의 다른 글
Spring의 @Controller, @Repository, @Service, @Component 등 알아보기 (0) | 2024.05.01 |
---|---|
Kotlin Sequence (스퀸스) 에 대해 알아보자 (1) | 2024.02.04 |
Spring에서 같은 type의 Bean 구분하는 방법 (0) | 2023.06.06 |
자바 21 - 자바 상속(Inheritance) (0) | 2021.05.21 |
자바 20 - UML 다이어그램 (1) | 2021.05.10 |