我正在研究通过使用内联函数来优化调用堆栈的大小。
如果执行以下代码:
inline fun function2( action: () -> Unit) {
action()
}
fun function1() {
function2{ printCurrentStack() }
}
fun printCurrentStack() {
RuntimeException().printStackTrace()
}
fun main() {
function1()
}
您将获得以下输出:
at com.kotlin.playground.functional.PrimeNumbersKt.printCurrentStack(PrimeNumbers.kt:17)
at com.kotlin.playground.functional.PrimeNumbersKt$function1$1.invoke(PrimeNumbers.kt:13)
at com.kotlin.playground.functional.PrimeNumbersKt$function1$1.invoke(PrimeNumbers.kt)
at com.kotlin.playground.functional.PrimeNumbersKt.function2(PrimeNumbers.kt:8)
at com.kotlin.playground.functional.PrimeNumbersKt.function1(PrimeNumbers.kt:13)
at com.kotlin.playground.functional.PrimeNumbersKt.main(PrimeNumbers.kt:21)
at com.kotlin.playground.functional.PrimeNumbersKt.main(PrimeNumbers.kt)
因此,在这种情况下,堆栈有 7 个元素。
- 打电话
main
- 打电话
function1
- 打电话
function2
- 2 次调用 lambda 表达式
- 打电话
printCurrentStack
- 打电话
printStackTrace
现在,如果我标记function2
为内联并执行代码,我会得到以下输出:
at com.kotlin.playground.functional.PrimeNumbersKt.printCurrentStack(PrimeNumbers.kt:17)
at com.kotlin.playground.functional.PrimeNumbersKt.function1(PrimeNumbers.kt:13)
at com.kotlin.playground.functional.PrimeNumbersKt.main(PrimeNumbers.kt:21)
at com.kotlin.playground.functional.PrimeNumbersKt.main(PrimeNumbers.kt)
这似乎很好用,调用堆栈的大小减少了 3。
但是,如果我更新function1
以在将 lambda 发送到变量之前将其存储在变量中function2
:
fun function1() {
val lambda = { printCurrentStack() }
function2(lambda)
}
输出变为:
at com.kotlin.playground.functional.PrimeNumbersKt.printCurrentStack(PrimeNumbers.kt:15)
at com.kotlin.playground.functional.PrimeNumbersKt$function1$lambda$1.invoke(PrimeNumbers.kt:10)
at com.kotlin.playground.functional.PrimeNumbersKt$function1$lambda$1.invoke(PrimeNumbers.kt)
at com.kotlin.playground.functional.PrimeNumbersKt.function1(PrimeNumbers.kt:21)
at com.kotlin.playground.functional.PrimeNumbersKt.main(PrimeNumbers.kt:19)
at com.kotlin.playground.functional.PrimeNumbersKt.main(PrimeNumbers.kt)
调用堆栈的大小从 4 变为 6,但function2
仍标记为inline
函数。
如果 lambda 存储在变量中,则似乎无法内联 lambda 调用。
为什么会这样?