Kotlin编程

Effective Kotlin. part 1

2017-06-22  本文已影响57人  yangweigbh

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

上一篇下一篇

猜你喜欢

热点阅读