inline 内联函数
编译时,会将 inline 内部逻辑,迁移到调用方内部,形成整体代码块。由于无需单独创建实例,所以运行效率比常规创建实例方式更高
// 此函数为内联函数,传入一个lambda表达式
inline fun inlineTest(block: () -> Unit) {
println("inlineTest")
block()
}
// 此函数为非内联函数,也是传入一个lambda表达式
fun test(block: () -> Unit) {
println("test")
block()
}
fun main() {
println(measureTimeMillis {
inlineTest {
println("main inlineTest")
}
})
println(measureTimeMillis {
test {
println("main test")
}
})
}
# inlineTest
main inlineTest
1
test
main test
9
inline函数执行时间为1,非inline函数执行时间为9
反编译后的内容
public final class MainKt {
public static final void main() {
// ①此处为inline函数的调用过程
long start$iv = System.currentTimeMillis();
System.out.println("inlineTest");
System.out.println("main inlineTest");
long var6 = System.currentTimeMillis() - start$iv;
System.out.println(var6);
// ②此处为非inline函数的调用过程
start$iv = System.currentTimeMillis();
test((Function0)null.INSTANCE);
var6 = System.currentTimeMillis() - start$iv;
System.out.println(var6);
}
// ③在编译器中可以看到此处inline函数并没有调用的地方
public static final void inlineTest(@NotNull Function0 block) {
Intrinsics.checkNotNullParameter(block, "block");
int $i$f$inlineTest = false;
System.out.println("inlineTest");
block.invoke();
}
public static final void test(@NotNull Function0 block) {
Intrinsics.checkNotNullParameter(block, "block");
System.out.println("test");
block.invoke();
}
// $FF: synthetic method
public static void main(String[] args) {
main();
}
}
noinline 不内联
noinline就是非内联的意思,也就是表明被noinline修饰的参数强制不允许内联,此参数作为一个普通的函数引用传递,并且noinline必须搭配inline使用
fun main() {
noinlineTest({
println("main inline")
}, {
println("main noInline")
})
}
// 定义一个内联函数,第一个参数可内联使用,第二个参数使用noinline修饰,强制不内联
inline fun noinlineTest(block: () -> Unit, noinline no: () -> Unit) {
println("noinlineTest")
block()
no()
}
# log
noinlineTest
main inline
main noInline
反编译后内容
public final class NoinlineKt {
public static final void main() {
// ① no参数为一个Function,直接实例化了
Function0 no$iv = (Function0)null.INSTANCE;
// ② noinlineTest函数中打印的日志
System.out.println("noinlineTest");
// ③ block函数内代码直接拷贝到这
System.out.println("main inline");
// ④ 执行no参数具体的代码
no$iv.invoke();
}
public static final void noinlineTest(@NotNull Function0 block, @NotNull Function0 no) {
Intrinsics.checkNotNullParameter(block, "block");
Intrinsics.checkNotNullParameter(no, "no");
int $i$f$noinlineTest = false;
System.out.println("noinlineTest");
block.invoke();
no.invoke();
}
// $FF: synthetic method
public static void main(String[] args) {
main();
}
}
crossinline
意思为强制内联的意思,它表示被修饰的lambda参数强制执行内联作用,一般我们见到的使用它的地方都是在内联函数中使用了lambda表达式,并且在此表达式调用了内联函数的lambda参数,此时如果不使用crossinline修饰参数,编译器会报错。
不常用