一、内联函数原理
使用高阶函数为开发带来了便利,但同时也产生了一些性能上的损失,官方是这样描述这个问题:
使用高阶函数会带来一些运行时的效率损失:每一个函数都是一个对象,并且会捕获一个闭包。 即那些在函数体内会访问到的变量。 内存分配(对于函数对象和类)和虚拟调用会引入运行时间开销,但是通过内联化 Lambda 表达式可以消除这类的开销。
为了解决这个问题,可以使用内联函数,用inline修饰的函数就是内联函数,inline修饰符影响函数本身和传给它的 Lambda 表达式,所有这些都将内联到调用处,即编译器会把调用这个函数的地方用这个函数的方法体进行替换,而不是创建一个函数对象并生成一个调用。
接下来用代码验证这个说法,先定义一个普通的高阶函数,然后调用两次:
fun calculate(a: Int, b: Int, cal: (Int, Int) -> String) {
println(cal(a, b))
}
fun main(args: Array) {
calculate(3, 7) { a, b ->
"$a + $b = ${a + b}"
}
calculate(3, 7) { a, b ->
"$a * $b = ${a * b}"
}
}
// 输出
3 + 7 = 10
3 * 7 = 21
这样其实是看不出什么问题的,Kotlin 文件编译后会生成对应的 class 文件,所以我们将 class 文件反编译成 Java 文件后再看。如果使用Android Studio或者IntelliJ IDEA,可以按照如下方式查看 Kotlin 文件对应反编译后的 Java 文件:
打开目标 Kotlin 文件
查看 Kotlin 文件字节码:Tools –> Kotlin –> Show Kotlin ByteCode
在 kotlin 文件字节码页面中点击左上角的 decompile 按钮,就会生成对应的 Java 文件
我们来看上边代码对应的 Java 代码: