当前位置: 首页>移动开发>正文

android kotlin view 代码设置宽高 kotlin-android

kotlin inline的作用:

// Kotlin
fun main(args: Array<String>) {
    multiplyByTwo(5)
}

fun multiplyByTwo(num: Int) : Int {
    return num * 2
}

通过Studio的 Tools -> Kotlin -> Show Kotlin Bytecode,然后再点击反编译

android kotlin view 代码设置宽高 kotlin-android,android kotlin view 代码设置宽高 kotlin-android_Kotlin,第1张

 

转化后的代码如下:

public final class Temp2 {
    public final void main(@NotNull String[] args) {
        Intrinsics.checkParameterIsNotNull(args, "args");
        int num$iv = 5;
        int var10000 = num$iv * 2;
    }

    public final int multiplyByTwo(int num) {
        int $i$f$multiplyByTwo = 0;
        return num * 2;
    }
}

可见,直接将第二个方法的代码复制到了第一个方法,减少了一层方法的调用

乍一看,的确的提高了运行效率,毕竟少用一个方法栈嘛。

然而?

建议不要使用 inline ?

一切看起来都很美好,除了 IDE 给我的刺眼提示。

Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types

大致意思是在这里使用内联对性能的影响微乎其微,或者说没有什么意义。Kotlin 的内联最好用在函数参数类型中。也就是说对于普通方法加上inline没啥意义。

Java 支持内联吗?

你可以说不支持,因为 Java 并没有提供类似 inline 的显示声明内联函数的方法。

但是 JVM 是支持的。Java 把内联优化交给虚拟机来进行,从而避免开发者的滥用。

典型的一种滥用, 内联超长方法 ,极大的增大字节码长度,反而得不偿失。你可以注意 Kotlin 标准库中的内联函数,基本都是简短的函数。

对于普通的函数调用,JVM 已经提供了足够的内联支持。因此,在 Kotlin 中,没有必要为普通函数使用内联,交给 JVM 就行了。

另外,Java 代码是由 javac 编译的,Kotlin 代码是由 kotlinc 编译的,而 JVM 可以对字节码做统一的内联优化。所以,可以推断出,不管是 javac ,还是 kotlinc,在编译期是没有内联优化的。

 

那么我们再看看在高阶函数上使用内联inline

fun main(args: Array<String>) {
    val message = "xxx"
    runCatch { println(message) }
}

fun runCatch(block: () -> Unit) {
    try {
        block()
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

//上面kotin代码 反编译成java代码后,如下
public final void main(@NotNull String[] args) {
   Intrinsics.checkParameterIsNotNull(args, "args");
   final String message = "xxx";
   this.runCatch((Function0)(new Function0() {
      // $FF: synthetic method
      // $FF: bridge method
      public Object invoke() {
         this.invoke();
         return Unit.INSTANCE;
      }

      public final void invoke() {
         String var1 = message;
         boolean var2 = false;
         System.out.println(var1);
      }
   }));
}

public final void runCatch(@NotNull Function0 block) {
   Intrinsics.checkParameterIsNotNull(block, "block");

   try {
      block.invoke();
   } catch (Exception var3) {
      var3.printStackTrace();
   }
}

可见,需要创建一个匿名内部类来实现。

如果加上内联,效果如下:

fun main(args: Array<String>) {
    val message = "xxx"
    runCatch { println(message) }
}

inline fun runCatch(block: () -> Unit) {
    try {
        block()
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

//上面kotlin代码 反编译成java代码后
public final void main(@NotNull String[] args) {
   Intrinsics.checkParameterIsNotNull(args, "args");
   String message = "xxx";
   boolean var4 = false;

   try {
      int var5 = false;
      boolean var7 = false;
      System.out.println(message);
   } catch (Exception var9) {
      var9.printStackTrace();
   }
}
//可见减少了匿名内部类的创建,直接代码合并了

总而言之,Kotlin 的 Lambda 为了完全兼容到 Java6,不仅增大了编译代码的体积,也带来了额外的运行时开销。为了解决这个问题,Kotlin 提供了 inline 关键字。

Kotlin 内联函数的作用是消除 lambda 带来的额外开销

 

那么,如果lambda表达式当作参数传递,又内敛了 那不得出问题?

fun main(args: Array<String>) {
    val message = "xxx"
    runCatch({ println(message) }, { println(message) })
}

/**
 * 注意:这里把block2 当作参数传递到下一个函数了
 * 由于使用了inline,所以必须在block2上加上noinline,不然报错
 * 被noinline修饰的函数类型参数不会被内联优化
 */
inline fun runCatch(block: () -> Unit, noinline block2: () -> Unit) {
    try {
        block()
    } catch (e: Exception) {
        e.printStackTrace()
    }

    //lambda当参数
    otherMethod(block2)
}

fun otherMethod(lambda: () -> Unit) {
    lambda.invoke()
    println("lambda当作参数的方法")
}

//上面kotlin代码 反编译成java代码如下:
public final void main(@NotNull String[] args) {
   Intrinsics.checkParameterIsNotNull(args, "args");
   final String message = "xxx";
   Function0 block2$iv = (Function0)(new Function0() {
      // $FF: synthetic method
      // $FF: bridge method
      public Object invoke() {
         this.invoke();
         return Unit.INSTANCE;
      }

      public final void invoke() {
         String var1 = message;
         boolean var2 = false;
         System.out.println(var1);
      }
   });
   boolean var5 = false;

   try {
      int var6 = false;
      boolean var8 = false;
      System.out.println(message);
   } catch (Exception var10) {
      var10.printStackTrace();
   }

   this.otherMethod(block2$iv);
}

public final void otherMethod(@NotNull Function0 lambda) {
   Intrinsics.checkParameterIsNotNull(lambda, "lambda");
   lambda.invoke();
   String var2 = "lambda当作参数的方法";
   boolean var3 = false;
   System.out.println(var2);
}

可见 加上noinline的参数,没有被内联

 

 




https://www.xamrdz.com/mobile/4v81961096.html

相关文章: