Kotlin内联函数比Java匿名类更便宜吗?

对了,我正在写一些这样的内容,所以我可能会有一些不正确的概念。


Java有能力写一个匿名函数。 当您有某种事件的监听器接口时,这非常有用。 举个例子:

button.setOnClickListener(new View.OnClickListener(View v) { @Override public void onClick(View v) { // handle the action here } }); 

匿名监听器将被编译为一个类似OnClickListener$1.class 。 这是Java语言的基础设计决定。 一切都是一个对象,甚至是匿名函数。

当你想编写一个功能更强大的代码库时,这成为一个问题。 大量的匿名类创建了大量的类数,这可能是受限制的平台(如Android)上的问题。

从源代码的角度来看,Kotlin函数更为头等。 我的问题是,Kotlin是否比Java对匿名类更有效地将这些函数编译成字节码,还是会遇到与Java中的大类类相同的问题?

谢谢,

简单的答案是肯定的 ,Kotlin内联函数非常便宜。

当编译内联函数调用时,传递给调用的lambda表达式被内联到函数体中,而函数体又在调用点处内联。 这允许编译器不为lambda体生成任何附加的类或方法。

编译一个内联函数

其中一张关于Kotlin 的幻灯片由@yole构建 。 不幸的是,我只用俄语发现了这个记录。 其他幻灯片也有一些兴趣,你可以在那里找到更多关于非内联lambda的信息。

通常,使用lambda表达式的内联函数的Kotlin代码的运行速度要快于使用lambdas或Streams的相同Java代码。 所有的代码绑定是在编译时完成的,没有虚拟方法调用的运行时间开销,也没有增加方法计数,这对于Android来说很重要。

过度内联的缺点是代码大小的增长:内联函数体的字节码的公共部分实际上在呼叫站点被复制。 此外,内联会使调试变得复杂,因为代码的行号和调用堆栈将与源文件中的行号和调用堆栈不同。 虽然IDE支持可以在这里帮助。

我建议你自己尝试内联函数:你可以很容易地检查生成的字节码 ; 当然,还要对性能至关重要的特定用例做一些基准测试。

Kotlin有一个inline关键字。 如果你使用这个关键字,不仅内联函数,而且你可以把lambda体看作只是一个嵌套的作用域级别,所以你可以从它return

示例(直接从文档)

 fun foo() { inlineFunction { return // OK: the lambda is inlined } } 

查看更多文档:

https://kotlinlang.org/docs/reference/inline-functions.html

编辑:

为了澄清你对性能的确切问题,这是文档中的第一段:

使用高阶函数会施加一定的运行时间惩罚:每个函数都是一个对象,它捕获一个闭包,即在函数体中访问的那些变量。 内存分配(对于函数对象和类)和虚拟调用都会引入运行时间开销。

但是在很多情况下,通过内联lambda表达式可以消除这种开销。

所以,据我所知,是的,它将内联功能,并消除否则会被强加的任何开销。

但是,这似乎只适用于您声明为inline函数。