Android性能优化之SparseArray

SparseArray是什么?如何实现优化?如何使用?

SparseArray是什么

官网
简单来说,SparseArray是一个从Interger到Object的映射Map,是Android里专门为 < Integer,Object >这样的hashmap而写的用于提高效率的类。正如其中文翻译稀疏矩阵,简单粗暴保存有效的数据信息,提高内存使用率。

特点:

  1. 比hashmap有更高的内存效率
  2. 使用折半查找,寻找key
  3. 不是很适合大数据项
  4. 比传统hashmap慢,但是对于几百项的数据而言,性能差距不到很大,小于50%

SparseArray优化方式

那么SparseArray是如何实现优化的呢?

  1. 避免自动装箱
  2. 每个映射不依赖多余的入口对象
  3. 每次删除数据时不立刻压缩数组,而是先标记为已删除,等下次相同的key重复使用或者等待垃圾回收时对所有移除的key一起处理。

SparseArray实现方式

SparseArray中成员定义

1
2
3
private int[] mKeys;//key按照大小排序
private Object[] mValues;//数值
private int mSize;//大小

下面的话说明了一个问题:对SparseArray的增删查改等操作。都是在mKeys,mValues,mSize操作。
是的!SparseArray的数据结构就是两个数组,这就是它内存优化的奥秘!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* 添加键值对到数组中,如果key已经存在就代替
*/
public void put(int key, E value) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);//二叉查找对应key是否存在

if (i >= 0) {
mValues[i] = value;//key已经存在直接赋值
} else {
i = ~i;

if (i < mSize && mValues[i] == DELETED) {//查看是否在标记删除的键中,在则重用被标记删除的空间

mKeys[i] = key;
mValues[i] = value;
return;
}

if (mGarbage && mSize >= mKeys.length) {//执行垃圾回收
gc();

// Search again because indices may have changed.
i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
}

mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);//插入key
mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);//插入value
mSize++;//size+1
}
}

而hashmap则由于节点指针,Table可能没有使用完全等问题对内存使用非常低!
参考:Java HashMap工作原理

SparseArray如何使用

1
2
3
4
5
6
SparseArray sparseArray = new SparseArray<String>();//此处String可用你自己的类型替换
spareArray.append(0,"hello");或者 spareArray.put(0,"hell0");//添加
int key =sparseArray.keyAt(1); //查找键
String value=(String) sparseArray.valueAt(1); //查找值
sparseArray.put(0, "jack"); 或者 sparseArray.setValueAt(0, "jack"); //修改
sparseArray.delete(0); //删除

参考:Android利用SparseArray替换使用HashMap

不足之处,请指教!
转载请注明出处@author:chenfengkg

-------------本文结束感谢您的阅读-------------
鼓励鼓励!