Android性能优化(中)

来源:互联网 发布:linux下cp命令的用法 编辑:程序博客网 时间:2024/06/05 21:49

Android性能优化(中)

1)ArrayMaps

HashMap好用,但却很占内存,简要原理如下:

这里写图片描述

官方推荐使用ArrayMap或SparseArray代替:

这里写图片描述

ArrayMap工作原理:
当你想获取某个value的时候,ArrayMap会计算输入key转换过后的hash值,然后对hash数组使用二分查找法寻找到对应的index,然后我们可以通过这个index在另外一个数组中直接访问到需要的键值对。如果在第二个数组键值对中的key和前面输入的查询key不一致,那么就认为是发生了碰撞冲突。发生冲突问题后会继续以key为中心点,分别上下展开,逐个去对比查找,直到找到匹配的值。

由于数组插入和删除效率不高,可在满足下面2个条件时使用ArrayMap:

  • 对象个数的数量级最好是千以内
  • 数据组织形式包含Map结构

2)SparseArray

稀疏数组就是数组中大部分的内容值都未被使用(或都为零),在数组中仅有少部分的空间使用。因此造成内存空间的浪费,为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。

这里写图片描述

3)AutoBoxing

Auto boxing(自动装箱),系统自动将基础数据类型装载到对象中,如下:

Integer num = 200;

等价于

Integer num = Integer.valueOf(200);

查看valueOf源码,可以看出当值在[-128, 127]区间内,是从IntegerCache对象池中获取一个Integer对象,超过这个区间,直接new一个新对象

public static Integer valueOf(int i) {    assert IntegerCache.high >= 127;    if (i >= IntegerCache.low && i <= IntegerCache.high)        return IntegerCache.cache[i + (-IntegerCache.low)];    return new Integer(i);}

因此Integer num = 200;触发了自动装箱,导致创建了多余的对象。

// 方式一(错误:多创建了83个对象)Integer total = 0;for (int i = 0; i<200; i++) {   total += i;}// 方式二(正确)int total = 0;for (int i = 0; i<200; i++) {   total += i;}

类似写法的还有

HashMap<Integer, String> map = new HashMap<>();map.put(200, "value");

为了避免这些autoboxing带来的效率问题,Android特地提供了一些如下的Map容器用来替代HashMap,不仅避免了autoboxing,还减少了内存占用:

这里写图片描述

4)ENUMs

Android官方强烈建议不要在Android程序里面使用到enum。

这里写图片描述

假设我们有这样一份代码,编译之后的dex大小是2556 bytes,下面是使用enum和static后dex大小比较:
这里写图片描述

5)Getters/Setters

直接访问某个字段可能要比通过getters方法来去访问这个字段快3到7倍

6)增强型for语句

这里写图片描述

7)other

使用StringBuffer或者StringBuilder来进行拼接字符串,而不是加号连接符,因为使用加号连接符会创建多余的对象;

使用基本数据类来代替封装数据类型,int比Integer要更加高效;

当一个方法的返回值是String的时候,如果明确知道返回的String用于拼接操作的话,可以返回一个StringBuffer对象来代替,因为这样可以将一个对象的引用进行返回,而返回String的话就是创建了一个短生命周期的临时对象;

使用系统封装好的API,例如系统提供的System.arraycopy()方法拷贝效率要比我们自己写个for循环拷贝快9倍以上;


Android性能优化(下)

原创粉丝点击