Android性能调整:ParseArray与Hashmap

Android ADT的最新更新之一是添加了Android Lint 。 Lint将检查您的Android项目中是否有您可以更改以改善应用程序的简单操作。 Lint会通知您以下信息:
  • 未使用的资源
  • 简单的代码更改即可提高性能
  • XML布局的效率低下,例如嵌套权重或未使用的布局

还有其他一些事情。 前几天运行Lint时,我发现了Lint建议的其他性能调整。 有人告诉我“对于键为整数类型的地图,使用Android SparseArray API 通常更为有效”。

但是什么时候应该使用SparseArray?

在检查了更多优化之后,我找不到大量数据说明何时Hashmap上使用SpraseArray 。 是否应该在本可以使用Hashmap的所有情况下使用它? 如果数组很小怎么办? 如果值的范围小于500怎么办?

这些是我尝试通过以下实验回答的问题。 但是在我直接进入实验细节之前,最好先了解一些有关Hashmaps和SparsArrays的背景信息。

什么是哈希图?

哈希图是一种包含“键值”对的数据结构。 它具有恒定的时间,即从数组中检索元素的O(1)时间要求。 这意味着无论大小如何,从数组中提取任何元素都需要花费相同的时间。 这可以通过使用散列函数来实现,该函数在给定输入键的情况下生成数组索引。

(在这种情况下)使用Hashmap将Integer键映射到对象。

什么是SparseArray?

要了解什么是SparseArray ,了解标准数组的工作原理将很有帮助。 数组实际上只是一个连续的内存块。 该块的大小对应于数组可以容纳多少个元素。 例如,如果一个对象需要10个字节的存储空间,并且创建了可以容纳5个这些对象的数组,则该数组具有50个字节的存储块。 数组中的每个对象都有一个10字节的段。 通过使用数组索引,您实际上是一次在数组的内存中移动,每次10个字节。

当您希望特定的索引映射到特定的对象,并且它们不能涵盖每个索引时,就会出现问题。 例如,如果您希望对象位于索引4和5,但不关心索引1、2或3,则最终会浪费数组内存。

为什么在Hashmap上使用SparseArray?

似乎SparseArray是比使用Hashmap将Integer映射到对象更有效的解决方案。 从理论上讲,在这种情况下,通过消除哈希函数处理时间,SparseArray可以比HashMap更快地添加和检索元素。

从SparseArray页面和Lint警告中可以看到,这里的语句非常模糊。

SparseArray一直都比Hashmap更好吗? 如果不是,那么HashMap何时比SparseArray更有效率?

本实验

为了比较这两种数据结构,我设计了一个快速简单的测试(和应用程序)。 基准测试可以评估以下步骤:

  1. 插入x个随机值(范围从0到y)
  2. 检索x个随机值(范围从0到y)

为了处理此实验,我编写了一个简单的Android应用,其中包含基本的UI和一些异步任务来进行上述实验(即将在Github上提供)。

对于实验,我测试了两个不同的变量:

  1. 数组大小从1,10,100,…,到1,000,000
  2. 数组中数字的范围从1、10、100,...到100,000,000

该应用程序在具有Android 2.3.4版本的Samsung Galaxy 2上运行。

结果 SparseArray结果

SparseArray是一种非常快速的数据结构,大小不超过10,000。 如果您要从数组中提取数据的数量远远超过添加到数组中的数据,那么您可以避免使用100,000个大小。 跃升至1,000,它开始放慢一点,但也不足为奇。

哈希图结果

执行摘要

Hashmap和SparseArray的性能非常相似,最大可达10,000个大小标记。 100,000个大小标记是发现一些有趣结果的地方。 对于检索100,000个大小的数组中的元素,一旦整数范围超过1,000,性能就会Swift下降。

因此,对于小于1000的数据结构大小(任何范围都可以),Hashmap和SparseArray看起来非常相似。 大小为1,000时,性能提升可能很小,如果有的话。

当大小增加到10,000标记时,两种数据结构都有不同的性能。 在此级别(上图中的黄色)中, Hashmap在添加对象时具有更高的性能,而SparseArray在检索对象时具有更高的性能。

如果大小为100,000(上图中的红色),则Hashmap会很快失去性能,达到100范围标记。 但是,SpraseArray仍然能够以可比的效率检索此范围内的元素 。 在达到1,000个范围限制后,它也会崩溃。

因此,有了上述所有有趣的内容,我便放弃了一些新理论:

  • 在Android(通常是移动编程)中,内存中的数据结构中包含10,000个以上的对象似乎是一个上限。
  • 对于较小的阵列(小于1,000),SparseArray和Hashmap的性能非常可比
  • 对于大于10,000的阵列,如果要添加的元素大于获取的元素,请尝试使用SparseArray。
  • 对于大于100,000的阵列,请尝试一下SparseArray…或修复您的应用程序设计,以使您没有任何庞大的内存中数据结构。

参考: Android Performance Tweaking: Programming Mobile博客上来自我们JCG合作伙伴 Isaac Taylor的ParseArray与Hashmap


翻译自: https://www.javacodegeeks.com/2012/07/android-performance-tweaking-parsearray.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值