Android 开发流行的一些传闻(Android Dev Summit 2019)


本文是Android Dev Summit 2019 系列视频的笔记第一篇。原视频见此。这个视频主要是把一些Android开发中有一部分所谓「优化」思路或者是先入为主的偏见逐一验证击破。

传闻:使用kotlin编写的app更加大,使用起来更慢?

用事实说话

Google Drive团队开始实践将项目中多达16000 多行的 java 代码转化成 kotlin 代码,最后的结果呢?请看图:

此次改动涉及16000多行代码,171 个代码文件,多达41 build target。但是对启动时间没有任何影响。如图所示,改动前后,启动时间均在2200多ms,其他性能数据也没有差别。但是他们代码行数将近减了25%。

这次总体改动后的收益为:

  1. 代码行数减少25%
  2. 通过工具测试后性能方面几乎没有差距
  3. 编译时间增长2%
  4. 编译后的代码大小增长2%

但是代码行数大量减少意味着代码维护工作以及代码出bug的几率也会大大减少。

所以综上所述,对于「使用kotlin编写的app更加大,使用起来更慢?」这个传闻是不实的。

传闻:通过Getters / Setters 方法访问model类属性会比直接访问属性更加耗时

如上图所示,大家可能以为通过get方法访问foo字段比起直接访问foo字段更加耗时,事实是这样的么?

然而作者通过专用的 Jetpack benchmark 库对两种形式进行测试,得到如下结果:

  1. 使用public 属性直接访问和通过getter方法访问完全没有区别;
  2. Android ART 虚拟机会将getter方法inline,导致最终和直接访问foo 属性效果一致

也就是说,在kotlin的世界里面:

tc.foo == tc.getFoo()

这里如果为了所谓的更快访问对应属性而将属性可见性改为 public 的行为不但没有带来性能上的优化,反而破坏了Java 的封装特性。

传闻:使用 Lambdas 表达式比使用内部类更好耗时

上面这两段代码在真实环境中会有区别吗?

同样,我们让数据说话。作者还是通过Jetpack benchmark 库对两种形式进行测试,得到如下结果:

  1. Lambdas 表达式的性能表现和内部类一致,几乎没有区别;
  2. 主要原因是Android 编译器在内部会先把Lambdas表达式翻译成匿名内部类,因此两者效果一致

基于上面的结论,作者推荐我们尽量使用lambdas表达式。这样能够保证代码更加简洁精确。

传闻:Android 虚拟机申请对象操作十分耗资源,我们应该尽量通过对象池来申请对象

坊间一直传闻Android开发中GC和对象申请都是十分耗时的操作,但是事实真的如此么?

首先Android平台的内存管理是一直都随着版本迭代在演进中。

如上图所示,Android 每个大版本都会在内存管理方面做一些优化,最新的几个版本里面的内存管理相对于最开始Android 2.0,3.0之类的远古版本应该是强大很多。Android 9.0 升级到 Android 10.0 以后所带来的GC优化效果如下图:

两个app在Android 9 和 Android 10 上面的GC提升都十分明显。

鉴于之前对Android 平台GC和对象创建都十分耗时的刻板印象,大家开始去寻找各种所谓优化的方式,其中最常见的就是使用对象池(Pool)来管理对象的创建和回收。

使用使用对象池(Pool)来管理对象的创建和回收就能减少GC的次数,提升app的用户体验么?

Pool<A> pool[] = new Pool<>[50];
void foo() {
    A a = pool.acquire();
    //.....
    pool.release(a);
}

对了,一般实现这样的对象池还需要保证线程同步。

为了对比直接创建对象和使用对象池在CPU上面的开销,作者通过Jetpack benchmark 库对两种形式进行测试(ch),得到如下结果:

从结果可以看出两者区别不大。

那么是不是我们就可以得出「直接创建对象」和「使用对象池进行对象管理」在当前的Android 平台上面已经没什么区别了?

其实还是得看情况,如果我们使用对象池,我们需要知道使用对象池的一些弊端:

  • 内存占用高
  • 内存中所持有的对象数比我们实际需要的要多
  • 实现一个高效的对象池管理类有一定门槛

但是碰到类似于大对象或者创建成本高的对象,使用对象池技术还是一个很不错的思路。

未完待续。。。


《“Android 开发流行的一些传闻(Android Dev Summit 2019)”》 有 1 条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注