原文链接:https://blog.csdn.net/Jaden_hool/article/details/78437947

方法调用流程

调用一个方法是一个压栈和出栈的过程,调用方法时将栈针压入方法栈,然后执行方法体,方法结束时将栈针出栈,这个压栈和出栈的过程会耗费资源,这个过程中传递形参也会耗费资源。

为什么需要inline?

有些简单的方法会被频繁调用,什么叫简单的方法呢,举个例子:

fun <T> check(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
} finally {
lock.unlock()
}
}

这个check方法的方法体中,不会将它的形参再传递给其他方法。我们调用一下 check 方法:

  check(l, {"我是lambda方法体"})//l是一个Lock对象

对于编译器来说,调用 check 方法就要将参数l和 lambda 表达式 {"我是 lambda方法体"} 进行传递,还要将 check 方法进行压栈出栈处理,这个过程就会耗费资源。

如果我们把 check 方法删除,直接执行 check 方法的方法体:

        l.lock()
try {
return "我是lambda方法体"
} finally {
l.unlock()
}

这样做的效果和调用 check方法是一样的,而且不需要压栈出栈了,但是代码是写给人看的,这样写明显产生了代码坏味道,老司机会告诉你,这几行代码需要抽成一个方法,避免多处调用产生冗余代码。于是你就老老实实把这几行代码抽成了 check方法,那么如上所述,一旦这个方法被频繁调用,压栈出栈将会带来性能问题。针对这个问题,kotlin 引入了 inline 关键字。我们在 check 方法前加上 inline关键字:

inline fun <T> check(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
} finally {
lock.unlock()
}
}

然后我们再调用 check 方法,编译器就会在编译期帮我们进行优化:

将我们写的代码

  check(l, {"我是lambda方法体"})//l是一个Lock对象

换成

        l.lock()
try {
return "我是lambda方法体"
} finally {
l.unlock()
}

也就是说 inline 关键字实际上增加了代码量,但是提升了性能,而且增加的代码量是在编译期执行的,对程序可读性不会造成影响。

其它

如果 check 方法中的参数需要传递给其他非 inline 方法:

inline fun <T> check(lock: Lock, body: () -> T): T {
lock.lock()
try {
otherCheck(body)//会报错
return body()
} finally {
lock.unlock()
}
} fun <T> otherCheck(body: ()-> T){ }

那么调用 otherCheck 是会报错的,因为 check 方法中的形参 body 现在已经 inline 了,不是一个函数对象了,也就不能作为一个参数传递了,除非在 body 参数前加上 noinline 关键字。

【转】Kotlin的inline内联函数的更多相关文章

  1. c++——inline内联函数

    1 inline内联函数 C++中的const常量可以替代宏常数定义,如: const int A = 3;  #define A 3 C++中是否有解决方案替代宏代码片段呢?(替代宏代码片段就可以 ...

  2. [C++] inline内联函数使用方法

    C++支持内联函数,目的是为了提高函数的执行效率,类似于C语言中的宏定义 内联函数在调用时将它在程序中的每个调用点展开,不用额外分配栈空间 内联函数的定义在一个源文件中出现一次,但在多个源文件中可以同 ...

  3. CG_INLINE,inline 内联函数

    内联函数,即在编译的时候将函数体替换函数调用,从而不需要将parameter,return address进行push/pop stack的操作,从而加速app的运行,然而,会增加二进制文件的大小. ...

  4. (inline)内联函数在IOS开发中的使用

    今天在阅读YYKit源码(https://github.com/ibireme/YYKit.git)时发现在YYKitMacro.h组件中大量使用的内联函数,例如此文件中的一个函数 static in ...

  5. inline内联函数

    demo //带参数的宏 #define MYFUNC(a, b) ((a) < (b) ? (a) : (b)) inline int myfunc(int a, int b) { retur ...

  6. C++ inline内联函数

    inline 函数避免函数调用的开销 // find longer of two strings const string &shorterString(const string &s ...

  7. 《C++ Primer》笔记-inline内联函数

    inline 函数避免函数调用的开销 // find longer of two strings const string &shorterString(const string &s ...

  8. C++语言基础(7)-inline内联函数

    函数调用是有时间和空间开销的.程序在执行一个函数之前需要做一些准备工作,要将实参.局部变量.返回地址以及若干寄存器都压入栈中,然后才能执行函数体中的代码:函数体中的代码执行完毕后还要清理现场,将之前压 ...

  9. C++对C语言的拓展(2)—— inline内联函数

    C语言中有宏函数的概念.宏函数的特点是内嵌到调用代码中去,避免了函数调用 的开销.但是由于宏函数的处理发生在预处理阶段,缺失了语法检测和有可能带来的语意差错. 1.内联函数基本概念 C++提供了 in ...

随机推荐

  1. Cocos Creator 资源加载流程剖析【六】——场景切换流程

    这里讨论场景切换的完整流程,从我们调用了loadScene开始切换场景,到场景切换完成背后发生的事情.整个流程可以分为场景加载和场景切换两部分,另外还简单讨论了场景的预加载. 加载场景的流程 load ...

  2. python3数据分析,安装学习

    python3数据分析,安装学习 转载注明来源: 本文链接 来自osnosn的博客,写于 2019-09-26. 为了简单.安装 anaconda3 就好啦. 因为安装原版python3,用pip安装 ...

  3. 计算几何 val.3

    目录 计算几何 val.3 自适应辛普森法 定积分 引入 辛普森公式 处理精度 代码实现 模板 时间复杂度 练习 闵可夫斯基和 Pick定理 结论 例题 后记 计算几何 val.3 自适应辛普森法 可 ...

  4. 一起学SpringMVC之国际化

    随着网络的发展,在Web开发中,系统的国际化需求已经变得非常的普遍.本文主要讲解SpringMVC框架对多语言的支持,仅供学习分享使用,如有不足之处,还请指正. 什么是国际化? 国际化(interna ...

  5. 《C#并发编程经典实例》学习笔记—3.1 数据的并行处理

    问题 有一批数据,需要对每个元素进行相同的操作.该操作是计算密集型的,需要耗费一定的时间. 解决方案 常见的操作可以粗略分为 计算密集型操作 和 IO密集型操作.计算密集型操作主要是依赖于CPU计算, ...

  6. English: Class GXX

    ######################################## GGGGG GG GG GG GG GGGG GG GGG GGGGGG author:enomothem date: ...

  7. Dockerfile编写

    Dockerfile 是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建编写命令: 1.FROM作用:声明使用哪个基础镜像格式:FROM IMA ...

  8. 服务守护DOS脚本

    创建一个批处理文件,复制以下内容至文件中并保存,右键文件名,以管理员身份运行.   @@@code  @echo off @echo 请使用管理员身份运行此脚本 rem 运行前先打开文件修改下列变量: ...

  9. C语言入门-类型定义

    一.自定义数据类型(typedef) c语言提供一个叫做typedef的功能来声明一个已有的数据类型的新名字,比如: typedef int length; 这样length成为了int类型的别名 这 ...

  10. ORM映射(对象关系映射)

    ORM映射(对象关系映射)分创建表和操作表两个部分创建单表创建关联表(foreignKey) 一对一 一对多(重点) 多对多(重点) 创建表后加str方法把打印的地址转换成对应字符表的操作(增删改查) ...