인라인 함수
- 함수를 호출하는 것이 아닌 바이트 코드를 호출 위치에 붙여넣는 형식
- 보통 람다를 인자로 넣을 경우 성능상 오버 헤드가 있으나 inline 키워드를 사용하여 람다 자체도 인라인 되어 오버헤드 감소
예시
inline fun runTwice(block: () -> Unit) {
block()
block()
}
사용 이유
- 성능 최적화 고차 함수 호출 시 생성되는 람다 객체, 함수 호출 오버헤드 감소
- 람다에서 non-local return 가능 일반적인 람다에선 return이 불가능하나 인라인 함수에서는 가능
inline fun doSomething(block: () -> Unit) {
println("Start")
block()
println("End")
}
fun main() {
doSomething {
println("In lambda")
return // main에서 return
}
println("This will NOT be printed") // 출력 안됨
}
주의 사항
- 큰 함수나 자주 변경될 함수에는 비효율적
- 코드의 크기가 증가됨
키워드
noinline
- 특정 람다는 인라인 하지 않도록 제어 가능
- 람다를 변수에 저장하거나 전달할 때 필요
inline fun wrap(block1: () -> Unit, noinline block2: () -> Unit) {
block1() // 인라인됨
block2() // 인라인 안됨
}
crossinline
- non-local return을 금지하는 키워드
- → return으로 바깥 함수 빠져나가는 걸 막음
inline fun runTask(crossinline task: () -> Unit) {
val r = Runnable {
task() // 여기서 return하면 오류! 그래서 crossinline 필요
}
r.run()
}
고차 함수의 최적화
고차함수
함수 자체를 인수로 받거나 반환하는 함수
fun doSomthing(action: () -> Unit) {
action()
}
고차 함수의 문제점
- 람다 객체 생성
- 외부 변수 참조때 추가 객체가 필요
- 간접 호출 비용 발생
→ 짧고 자주 호출되는 함수일 수록 성능 비용 과다 발생!
inline함수 사용
inline fun doSomthing(action: () -> Unit) {
action()
}
- 컴파일 타임에 함수 호출부에 함수 본문이 직접 삽입
→ 람다도 복사됨!
→ 람다 객체가 생성되지 않음
→ 간접 호출도 제거됨!
주의점
- inline을 많이 사용하면 코드의 크기가 커짐 → binary size 증가
- 람다 블럭이 큰 경우에는 오히려 비효율적
- 재귀 함수, suspend 함수 등 일부 상황에서는 inline이 불가능하거나 제한적임
- 재귀함수: 인라인 함수는 호출된 위치에 코드가 복사되므로 자기 자신을 복사하는 꼴이 되어 무한 루프
- suspend: inline함수는 JVM 바이트 코드로 인라인될 수 있어야하나, suspend 함수는 코루틴 상태 머신으로 변환되어 인라인과 충돌
- Non-local return 제한: noinline에서는 사용이 불가능
더보기
🔗 suspend 자세히 알아보기: [코틀린/Kotlin] 코루틴/Coroutine
[코틀린/Kotlin] 코루틴/Coroutine
코루틴 기초가벼운 비동기 처리 방식기존의 Thread, Callback 기반보다 간결하고 안전하게 비동기 작업 처리 가능코루틴 사용 이유복잡한 콜백 지옥(callback hell) 제거UI 스레드 방지동기식처럼 읽히
huiwoo-devlog.tistory.com
문제
1. 다음 조건을 만족하는 measureTime 인라인 함수를 구현하세요.
[조건]
- measureTime 함수는 인자로 고차 함수 block: () -> T 를 받습니다.
- block 함수를 실행하기 전과 후의 시간을 측정해, 소요 시간을 밀리초 단위로 출력합니다.
- 최종적으로 block()의 리턴값을 반환합니다.
- 함수는 inline으로 선언되어야 합니다.
[사용 예시]
fun main() {
val result = measureTime {
Thread.sleep(500) // 0.5초 대기
"Done!"
}
println("Result: $result")
}
[출력 예시]
Time: 500ms
Result: Done!
답:
inline fun <T> measureTime(block: () -> T): T {
val start = System.currentTimeMillis()
val result = block()
val end = System.currentTimeMillis()
println("${end - start}ms")
return result
}
보충: return이 String인 경우
inline fun measureTime(block: () -> Unit): String {
val start = System.currentTimeMillis()
block()
val end = System.currentTimeMillis()
return "${end - start}ms"
}
'개발새발 > 코틀린' 카테고리의 다른 글
[코틀린/Kotlin] 메모이제이션(Memoization) (0) | 2025.09.02 |
---|---|
[코틀린/Kotlin] 재귀(Recursion) (1) | 2025.09.01 |
[코틀린/Kotlin] 위임(Delegation) (2) | 2025.08.28 |
[코틀린/Kotlin] 코루틴(Coroutine) (3) | 2025.08.28 |
[코틀린/Kotlin] sealed class/when (0) | 2025.08.22 |