原文链接: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. JQuery 基本使用、操作样式、简单动画

    JQ与JS JQ是JS写的插件库,就是一个JS文件 凡是用JQ能实现的,JS都能实现,JS能实现的,JQ不一定能实现 引入 BootCDN:https://www.bootcdn.cn/jquery/ ...

  2. 查看python版本多少位的

    正常我们在cmd终端输入python之后,如果有安装python,就会在回车之后出来关于你安装的python版本信息,几版本,多少位的,但是还有一种,像我这样只显示了python版本是3.7.5,并没 ...

  3. Android——application全局类的使用

    目录 1.概述 2.Application基类 3.自定义Application类 4.Application的生命周期 5.Application对象的回调函数 6.Application对象的作用 ...

  4. Path Manipulation 路径操作

  5. SpringCloudConfig对称加密 yml配置文件while parsing a block mapping

    错误的配置!!! #-----------------db------------------ mybatis: type-aliases-package: com.book.product.pojo ...

  6. centos安装go环境

    centos安装go环境 1,下载合适的go安装包 https://studygolang.com/dl 2 上传到 centos服务器的 /usr/local下然后解压 3.设置go的环境变量    ...

  7. Create a Report at Runtime 在运行时创建报表

    In this lesson, you will learn how to create reports at runtime. A report showing a list of Tasks wi ...

  8. 腾讯,华为,阿里…7家Java后端面试经验大公开!

    感觉面试还是主要围绕简历来问的,所以不熟悉的东西最好不要随便写上去.项目和基础都很重要,整体的基础知识的框架可以参考GitHub 上 CYC2018的博客,分类很全,但是深入的学习还是要自己去看书,写 ...

  9. 将 云数据库MongoDB(阿里云)物理备份文件下载恢复至本地自建数据库 遇到的5个问题

    有时候我们可能需要将云上数据库下载到本地,下面是我们在操作MongoDB数据库时遇到的五个小问题. 其实现在RDS的 帮助文档 写的都比较详细了,大家在第一次操作时,可以细读一下,避免一些不必要的问题 ...

  10. datatable的dom配置

    l - Length changing 改变每页显示多少条数据的控件 f - Filtering input 即时搜索框控件 t - The Table 表格本身 i - Information 表格 ...