使用优化过的数据结构来保存数据是Android性能优化的步骤之一,最典型的就是使用SparseArray Family (SparseArray、ArrayMap....),使用教程:英文-官方教程Android Performance Patterns和中文-Android性能优化典范第三季。但是在使用SparseArray Family 时有几点是需要注意的,否则没有办法发挥出SparseArray Family 优秀的性能。
1. SparseArray Family 不适宜在大数据量上使用(1000+之后).
2. SparseArray Family 在小数据量时效果不明显(十几,几十个时).
3. 映射型的数据结构.
4. 不能序列化.
下面就通过测试用例来说明不同数据量时SparseArray Family 的使用效率。
由于SparseArray Family 的内部结构同ArrayMap 相似,仅以ArrayMap作为测试数据结构。
一、查询
测试用例:遍历数据集,并打印出Value值:
arrayMap = new ArrayMap<>();
hashMap = new HashMap<>();
int count = 9000; // set what you want
for (int i = 0; i < count; i++){
arrayMap.put(String.valueOf(i), String.valueOf(i));
hashMap.put(String.valueOf(i), String.valueOf(i));
}
//Query
long currentTime = System.currentTimeMillis();
for (int i = 0; i < arrayMap.size(); i+=2){
Log.d("test", "array map value: " + arrayMap.get(String.valueOf(i)));
}
long finishTime = System.currentTimeMillis();
Log.d("test", "arrayMap time: " + (finishTime - currentTime));
currentTime = System.currentTimeMillis();
for (int i = 0; i < hashMap.size(); i+=2){
Log.d("test", "hash map value: " + hashMap.get(String.valueOf(i)));
}
finishTime = System.currentTimeMillis();
Log.d("test", "hashMap time: " + (finishTime - currentTime));
数据量 | ArrayMap | HashMap |
---|---|---|
15 | 0 | 0 |
600 | 4 | 5 |
1400 | 10 | 11 |
9000 | 90 | 61 |
测试结果(耗时,单位:毫秒):
数据量 | ArrayMap | HashMap |
---|---|---|
15 | 0 | 0 |
600 | 4 | 5 |
1400 | 10 | 11 |
9000 | 90 | 61 |
为什么我发不出表格?
<br />
由此说明,在数据量较小时,查询效率基本没有区别,而大数据量时,SparseArray Family 和 ArrayMap 的查询效率比传统数据结构更差。
二、插入删除
测试用例:遍历数据集,删除Key为偶数的数据,同时打印所删除数据的Value值:
arrayMap = new ArrayMap<>();
hashMap = new HashMap<>();
int count = 9000; //set what you want
for (int i = 0; i < count; i++){
arrayMap.put(String.valueOf(i), String.valueOf(i));
hashMap.put(String.valueOf(i), String.valueOf(i));
}
//Remove
long currentTime = System.currentTimeMillis();
for (int i = 0; i < count; i+=2){
Log.d("test", "array map value: " + arrayMap.remove(String.valueOf(i)));
}
long finishTime = System.currentTimeMillis();
Log.d("test", "arrayMap time: " + (finishTime - currentTime));
currentTime = System.currentTimeMillis();
for (int i = 0; i < count; i+=2){
Log.d("test", "hash map value: " + hashMap.remove(String.valueOf(i)));
}
finishTime = System.currentTimeMillis();
Log.d("test", "hashMap time: " + (finishTime - currentTime));
数据量 | ArrayMap | HashMap |
---|---|---|
15 | 0 | 0 |
800 | 9 | 9 |
1300 | 22 | 11 |
9000 | 305 | 80 |
测试结果(耗时,单位:毫秒):
数据量 | ArrayMap | HashMap |
---|---|---|
15 | 0 | 0 |
800 | 9 | 9 |
1300 | 22 | 11 |
9000 | 305 | 80 |
为什么我发不出表格?
<br />
可以看到,在大数量时,SparseArray Family 同传统数据结构相比较时,在插入删除方面的性能更差,因此,不要在大数量时使用SparseArray Family的数据结构。
总结:当然,SparseArray Family最大的优势在于节省了大量的内存空间,详见stackoverflow上的讨论 SparseArray vs HashMap.