Android 性能优化——小心自动装箱(Autoboxing)

请保持淡定,分析代码,记住:性能很重要。

自动装箱引发的血案

有时性能瓶颈是由小问题累积到一起产生的。

一个典型的例子就是 Java 的自动装箱功能。自动拆装箱的目的就是自动地将基础类型与它们的对象版本相互转化,这样你就不用操心你代码中的这些转化了。例如 Integer value = 0 当中,将整型的 0 自动的转化为 Integer 的对象。

Java 的基础类型及其大小如下表:

基本类型存储大小
byte8 bits
short16 bits
int32 bits
long64 bits
float32 bits
double64 bits
char16 bits
boolean8 bits

为了在泛型集合中使用基础类型的功能,Java 提供了对应的对象版本,提供了与基础整型相同的功能,但可以使用于泛型集合。

基本类型对象
bytejava.lang.Byte
shortjava.lang.Short
intjava.lang.Integer
longjava.lang.Long
floatjava.lang.Float
doublejava.lang.Double
charjava.lang.Character
booleanjava.lang.Boolean

这种机制给代码编写带来了方便,举个例子:

// Primitive version
int total = 0;
for (int i = 0; i < 100; i++) {
  total += i;
}

// Generic version
Integer total = 0;
for (int i = 0; i < 100; i++) {
  total += i;
}

当我们需要使用 total 时,使用第二个版本更方便,看起来你不需要写多余的代码就把事情完成了,事实上,第二个版本是这样子的:

// Generic version
Integer total = 0;
for (int i = 0; i < 100; i++) {
  //total += i;
  // create new Integer()
  // push in new value
  // add to total
}

可以看到每次加上之前都要创建新的整数对象,将这个和第一个基础版本相比有着双重影响。

第一,这占用更多的内存,因为整形只有 4 字节,整数对象有 16 字节;

第二,创建对象需要耗费更多性能。不仅在循环中会出现这样的问题,当你在集合中使用基础类型时,也会出现这样的问题,特别地,对于 HashMap 这样的容器,只要你使用了基础类型,在进行插入、编辑或检索时就会产生一个基础类型和装箱对象。

为了避免 HashMap 的自动装箱行为,Android 系统提供了 SparseBoolMap,SparseIntMap,SparseLongMap,LongSparseMap 等容器,可减少运行时间开支,减少内存使用。它们与 HashMap 的简单对比如下:

容器构造
HashMap<obj, obj>
SparseBoolMap<bool, obj>
SparseIntMap<int, obj>
SparseLongMap<long, obj>
LongSparseMap<long, obj>

确定自动装箱产生问题的位置

解决问题的前提是要先找到问题的所在,Android Studio 有两种工具可以帮你找到自动装箱产生问题的位置。

1) Allocation Tracker

如果你使用 Allocation Tracker(分配追踪器)发现同一个地方分配了大量整数对象 java.lang.Integer 时,要特别注意。

2) TraceView

在 TraceView 中,要注意任何大量调用 java.lang.Integer.valueOf 的地方。

以上这两个迹象都是自动封装将产生问题的信号。

正如本文所述,性能优化时有些问题是很容易发现和修复的,但是这些小问题会逐步积累,而不加检查时则可能造成例如响应迟钝这样的大问题。

资料来源: Google 官方培训视频 Android Performance Patterns: Beware Autoboxing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值