kotlin 内联函数 inline

高阶函数实现的原理:函数类型其实是生成了一个对象 。

inline翻译成中文的意思就是内联 ,在kotlin里面inline被用来修饰函数,表明当前函数在编译时是以内嵌的形式进行编译的,从而减少了一层函数调用栈:

Kotlin 复制代码
inline fun fun1() {
    Log.i("tag", "1")
}
 
//调用
fun mainFun() {
    fun1()
}
 
//实际编译的代码
fun mainFun() {
    Log.i("tag", "1")
}

这样写的一点好处就是调用栈会明显变浅:

但是这个好处对应用程序的优化影响非常小,几乎可以忽略不计。甚至可能会由于多处调用代码重复编译导致编译字节码膨胀从而造成包体积变大的问题,这就得不偿失。

我们都知道kotlin允许函数可以作为另一个函数的入参对象进行调用,在实际调用处入参的函数体会被创建为一个对象:

Kotlin 复制代码
fun fun1(doSomething: () -> Unit) {
    Log.i("tag", "1")
    doSomething()
}
 
//调用
fun mainFun() {
    fun1 {
        Log.i("tag", "2")
    }
}
 
//实际编译的代码
fun mainFun() {
    val f = object: Function0<Unit> {
        override fun invoke() {
            Log.i("tag", "2")
        }
    }
    fun1(f)
}

一般情况下上图所示的调用逻辑并没有什么问题,创建一个小对象并不会对性能造成什么影响,但是如果我们将fun1放入for循环中呢:

Kotlin 复制代码
fun mainFun() {
    for (i in 0..1000) {
        fun1 {
            Log.i("tag", "2")
        }
    }
}

在短时间内就会在mainFun函数中循环创建1000个f对象,这样应用进程的内存会瞬间飙升并造成某些性能上的严重问题,这就类似于为什么不让在onDraw函数中创建局部对象。

而作为fun1函数的创建者,我们无法知道调用者会在什么场景以及时机去调用fun1函数,一旦出现上述重复创建大量函数对象的场景那么就会有严重的性能问题,而且这也是kotlin高阶函数的一个性能隐患。所以,基于这个问题kotlin提供了inline关键字来解决。

inline关键字可以将函数体内部的代码内联到调用处,甚至还可以将函数体内部的内部的代码也内联过去,而这个内部的内部的指的就是函数内部的函数类型的参数:

Kotlin 复制代码
inline fun fun1(doSomething: () -> Unit) {
    Log.i("tag", "1")
    doSomething()
}
 
//调用
fun mainFun() {
    for (i in 0..1000) {
        fun1 {
            Log.i("tag", "2")
        }
    }
}
 
//实际编译的代码
fun mainFun() {
    for (i in 0..1000) {
        Log.i("tag", "1")
        Log.i("tag", "2")
    }
}

这样就避免了函数类型的参数所造成的临时函数对象的创建,我们就可以在界面高频刷新、大量循环的场景下放心调用fun1函数了。

扩展:

Kotlin的 noinline和crossinline关键字-CSDN博客

总结

总的来说,inline关键字让函数以内联的方式进行编译避免创建函数对象来处理kotlin高阶函数的天然性能缺陷。同时,之前的文章中提到的kotlin的泛型实化,也是利用了inline关键字可以内嵌函数代码的特性而衍生出来的全新功能。

相关推荐
榴莲CC4 分钟前
VK1620 抗噪数显LED驱动芯片数码管显示IC内置 RC振荡器/8级整体亮度可调
前端
@Autowire8 分钟前
Layout-box-sizing是 CSS 中控制元素盒模型计算方式的核心属性,直接决定了元素的 width/height 是否包含内边距和边框
前端
alamhubb8 分钟前
反感pnpm的全链路污染?可以了解下这个对原项目零侵入,零修改完全兼容npm的monorepo工具
前端·javascript·node.js
叁两9 分钟前
“死了么”用户数翻800倍,估值近1亿,那我来做个“活着呢”!
前端·人工智能·产品
rannn_11131 分钟前
【Java项目】中北大学Java+数据库课设|校园食堂智能推荐与反馈系统
java·数据库·后端·课程设计·中北大学
AdleyTales37 分钟前
vscode识别不了@提示找不到路径解决
前端·javascript·vscode
NE_STOP39 分钟前
SpringBoot-shiro-jwt-dubbo-redis分布式统一权限系统(完结)
java
zfj32144 分钟前
java函数式接口 @FunctionalInterface用法
java·函数·function
去哪儿技术沙龙1 小时前
去哪儿网前端代码自动生成技术实践
前端·ai编程
TracyCoder1231 小时前
并发编程(二):Java原子类(Atomic Classes)全解析
java·原子类·atomic