高阶函数是否有任何成本?我可以很容易地解决一些问题,但我不确定它是否会影响性能。对它有任何限制吗?
答案 0 :(得分:5)
传递给高阶函数的Lambdas被编译为通用Function
对象。当涉及原始类型时,这种方法肯定会增加一些成本,也是由于装箱开销。
所以是的,它会影响性能。只要有意义,您就应该使用inline
更高阶函数,因为前面提到的警告将不再有问题。
取自文档:
使用高阶函数强加某些运行时惩罚:每个函数都是一个对象,它捕获一个闭包,即在函数体中访问的那些变量。内存分配(包括函数对象和类)和虚拟调用都会引入运行时开销。
但似乎在很多情况下,通过内联lambda表达式可以消除这种开销。
但inline
存在某些限制。请阅读docs。
高阶函数和来电代码的定义:
fun hoFun(func: (Int) -> Boolean) {
func(1337)
}
//invoke with lambda
val mod = 2
hoFun { it % mod == 0 }
字节码Java表示:
public static final void hoFun(@NotNull Function1 func) {
Intrinsics.checkParameterIsNotNull(func, "func");
func.invoke(1337);
}
final int mod = 2;
hoFun((Function1)(new Function1() {
public Object invoke(Object var1) {
return this.invoke(((Number)var1).intValue());
}
public final boolean invoke(int it) {
return it % mod == 0;
}
}));
如上所述,lambda被编译为Function
对象。每次调用都会导致实例化新的Function
对象,因为需要捕获mod
。非捕获lambda使用单例Function
实例。
将inline
修饰符应用于高阶函数时,编译的调用看起来要好得多:
int mod = 2;
int it = 1337;
if (it % mod == 0) {
;
}