Local functions
fun someMath(a: Int): Int {
fun sumSquare(b: Int) = (a + b) * (a + b)
return sumSquare(1) + sumSquare(2)
}
以上local funtion编译为java后其实是由匿名内部类实现的,每次调用local function就会创建一个Function对象,同时涉及到参数的box和unbox
public static final int someMath(final int a) {
Function1 sumSquare$ = new Function1(1) {
// $FF: synthetic method
// $FF: bridge method
public Object invoke(Object var1) {
return Integer.valueOf(this.invoke(((Number)var1).intValue()));
}
public final int invoke(int b) {
return (a + b) * (a + b);
}
};
return sumSquare$.invoke(1) + sumSquare$.invoke(2);
}
解决方法:使用non-capture local function。每次调用会重用同一Function,并且没有参数box和unbox
Null safety
fun sayHello(who: String) {
println("Hello $who")
}
kotlin public 方法中non-null参数编译为Java后有一个Intrinsics的静态方法调用(overhead很小)。(private 方法没有,因为由kotlin编译器保障)
public static final void sayHello(@NotNull String who) {
Intrinsics.checkParameterIsNotNull(who, "who");
String var1 = "Hello " + who;
System.out.println(var1);
}
要想去掉这些静态方法,使用编译器选项-Xno-param-assertions或者在proguard文件中使用rule:
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
}
Nullable primitive types
a nullable type is always a reference type
primitive type变量定义为nullable type会进行box。使用non-nullable type则可以避免box, 直接使用primitive type
About arrays
如果要创建primitive type的数组,总是使用IntArray, FloatArray等,不要使用泛型Array<T>,因为会导致box
Varargs
当调用vararg参数的函数时,会创建一个新的数组,这样会产生性能损耗。
fun printDouble(vararg values: Int) {
values.forEach { println(it * 2) }
}
printDouble(1, 2, 3)
printDouble(new int[]{1, 2, 3});
尽量避免使用vararg,而是将参数声明为Array
Refer:
https://medium.com/@BladeCoder/exploring-kotlins-hidden-costs-part-2-324a4a50b70
网友评论