误区三:Lambda 比内部类慢
Lambda(尤其是在引入 Stream API 的情况下)是一种非常方便的语法,可实现非常简洁的代码。如下这段代码,对对象数组的内部字段值求和,这里,使用了 Stream API 搭配 map-reduce 操作:
ArrayList array = build();
int sum = array.stream().map(tc -> tc.foo).reduce(0, (a, b) -> a + b);
第一个 lambda 会将对象转换为整数,第二个 lambda 会将产生的两个值相加。
下面代码中,我们再将 lambda 表达式换成内部类:
ToyClassToInteger toyClassToInteger = new ToyClassToInteger();
SumOp sumOp = new SumOp();
int sum = array.stream().map(toyClassToInteger).reduce(0, sumOp);
这里,有两个内部类:一个是 toyClassToInteger,它可以将对象转换为整数,第二个 SumOp 用来做求和运算。
从语法上看,第一个带有 lambda 的示例显然更优雅,也更易读。那么,性能差异又如何呢?我们再次在 Pixel 3 上使用了 Jetpack Benchmark,也没有发现性能差异:
从图中可以看到,我们还定义了单独的外部 (top-level) 类一起来做比较,发现性能都没有什么差异,原因就是 lambda 表达式最终也会被转换为匿名内部类。因此,为了代码的简洁易读,在这种场景下 lambda 表达式就是第一选择。
误区四:对象分配开销过大,应该使用对象池
Android 内置了最先进的内存分配和垃圾回收机制,如下图所示,几乎每个版本的更新都在对象分配方面做各式各样的更新。
各个版本之间的垃圾收集性能都有显著的改善,如今,垃圾收集对应用程序的流畅已经几乎没有影响了。下图展示了 Google 官方在 Android 10 中对具有分代并发收集的对象收集所做的改进,新版本的 Android 11 中也有明显的改进。
在 GC 基准测试(例如 H2)中,吞吐量大幅提高了 170% 以上,而在实际应用(如 Google Sheets)中,吞吐量也提高了 68%。
如果认为垃圾收集效率低下并且内存分配负担很重,那么就相当于认为创建的垃圾越少,垃圾收集工作就越少,因此,代替每次使用时都创建新对象,我们可以维护一个经常使用的类型的对象池,然后从池中获取已创建的对象,如下:
Pool pool[] = new Pool<>[50];
void foo() {
A a = pool.acquire();
…
pool.release(a);
}
这里省略了代码细节,大体就是就是定义了一个 pool,从 pool 中获取对象,然后最终释放。
要测试这种场景,我们使用微基准测试 (microbenchmark):从池中测试分配对象的开销,以及 CPU 的开销,来确定垃圾回收是否会影响应用程序的性能。
在这种情况下,我们依然可以在装有 Android 10 的 Pixel 2 XL 上循环运行了数千次分配对象的代码,因为对于小型或大型对象,性能可能会有所不同,我们还通过添加不同的字段来模拟不同的对象大小,最终的开销结果如下:
用于垃圾回收的 CPU 开销的结果如下:
从图中可以看出,标准分配和池化对象之间的差异也很小,但是,当涉及到较大对象的垃圾回收时,池解决方案略微高一点。
这个结果并不意外,因为池化对象会增加应用的内存占用量,此时,应用突然占用了太多的内存,即使由于池化对象减少了垃圾回收调用的数量,每个垃圾回收调用的成本也更高,因为垃圾收集器必须遍历更多的内存才能确定哪些对象需要被收集,哪些对象需要保留。
那么,对象是否应该被池化,这还是主要取决于应用的需求。如果不考虑到代码复杂性,池化对象有如下缺点:
-
提高内存占用量
-
使对象存活变长
-
需要非常完善的对象池机制
但是,池的方法对于大并且耗时的对象分配可能确实是有效的,关键是要记住在选择方案之前进行充分的测试。
误区五:debug 模式下进行性能分析
在 debug 的同时对应用进行性能分析非常方便,毕竟,我们通常也是在 debug 模式下进行编码的,并且,即使 debug 应用中的性能分析不准确,也可以更快地进行迭代修改提高效率,然后事实是并没有。
为了验证这一误解,我们分析了 Activity 相关的常见操作过程过的测试结果,如下图:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
资源分享
- 最新大厂面试专题
这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等
- 对应导图的Android高级工程师进阶系统学习视频
最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!
据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等
[外链图片转存中…(img-vDxwfhhn-1710766696462)]
- 对应导图的Android高级工程师进阶系统学习视频
最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!
[外链图片转存中…(img-VZ8FOSRC-1710766696463)]
下载方法:点赞+关注后 点击【Android高级工程师进阶学习】即可领取!