Kotlin-inline:你需要知道的一切(Android)

10 篇文章 0 订阅

“使用高阶函数会带来一定的运行时惩罚:每个函数都是一个对象,它会捕获一个闭包。闭包是可以在函数体中访问的变量范围。内存分配(函数对象和类)和虚拟调用会引入运行时开销。

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

让我们一起探索……

fun main() {
    me({
        println(it)
    }, {
        println(it)
    })
}

fun me(myName: (String) -> Unit, myAge: (Int) -> Unit) {
    myName("Christiano")
    myAge(36)
}

如果没有 inline 关键字,如果您看到 Kotlin 字节码,您会注意到创建了两个特殊函数类型的新实例。两个新实例将分配内存。

但是,这里也会发生额外的方法调用。仔细查看 Kotlin 反编译代码。

myName.invoke("Christiano");
myAge.invoke(36);
// (Function1)null.INSTANCE, (Function1)null.INSTANCE 
// instance of two higher order function

当执行上述这些代码时,它还会创建两个新函数。因此内存开销。

Kotlin 字节码反编译(Java 代码)

public final class TestInlineKt {
   public static final void main() {
      me((Function1)null.INSTANCE, (Function1)null.INSTANCE);
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }

   public static final void me(@NotNull Function1 myName, @NotNull Function1 myAge) {
      Intrinsics.checkNotNullParameter(myName, "myName");
      Intrinsics.checkNotNullParameter(myAge, "myAge");
      myName.invoke("Christiano");
      myAge.invoke(36);
   }
}

因此,创建特殊类型的新特殊实例并分配内存。额外的方法调用总是发生。

使用内联函数,没有额外的对象分配和额外的方法调用。让我们看看反编译代码。

public static final void main() {
      int $i$f$me = false;
      String it = "Christiano";
      int var2 = false;
      System.out.println(it);
      int it = 36;
      var2 = false;
      System.out.println(it);
}

在内联函数的帮助下,没有额外的方法调用,而是直接替换到主代码中。

由于 inline 关键字,编译器将内联函数的内容复制到调用站点,从而避免创建新的函数对象。

使用 inline 关键字反编译代码

public final class TestInlineKt {
   public static final void main() {
      int $i$f$me = false;
      String it = "Christiano";
      int var2 = false;
      System.out.println(it);
      int it = 36;
      var2 = false;
      System.out.println(it);
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }

   public static final void me(@NotNull Function1 myName, @NotNull Function1 myAge) {
      int $i$f$me = 0;
      Intrinsics.checkNotNullParameter(myName, "myName");
      Intrinsics.checkNotNullParameter(myAge, "myAge");
      myName.invoke("Christiano");
      myAge.invoke(36);
   }
}

看到没有对象分配。转到工具-> Kotlin-> 显示 Kotlin 字节码。现在搜索新关键字。因此,您将在字节码中找不到新关键字。

笔记:

  • 不要对大函数使用 inline 关键字。
  • 不要在没有高阶函数作为参数的情况下使用 inline 关键字。因为您不会获得显着的性能优势。

最后,如果大伙有什么好的学习方法或建议欢迎大家在评论中积极留言哈,希望大家能够共同学习、共同努力、共同进步。

小编在这里祝小伙伴们在未来的日子里都可以 升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰!!

不论遇到什么困难,都不应该成为我们放弃的理由!

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,需要一份小编整理出来的学习资料的关注我主页或者点击扫描下方二维码免费领取~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值