精通安卓性能优化-第一章(六)

本文探讨了Java中关键数据结构的选择与使用,包括java.util包内的核心结构及Android特有结构如LruCache、SparseArray等。强调了合理选择数据结构的重要性,并提供了优化建议。

数据结构

像在不同的Fibonacci实现中展示的那样,好的算法和数据结构是能够快速运行的应用程序的关键因素。你需要对Android和Java定义的许多数据结构比较熟悉,可以快速的针对需求选择合适的数据结构。考虑选择合适的数据结构是开发最的高优先事情之一。

在java.util包中的主要数据结构列在图1.1中。

图1-1 Java.util包中的数据结构



安卓添加了一些独有的数据机构,通常是为了解决常见问题或者提升性能。
(1)  LruCache
(2)  SparseArray
(3)  SparseBooleanArray
(4)  SparseIntArray
(5)  Pair

NOTE: Java同样定义了Arrays和Collections类。这两个类仅包含静态方法,分别对arrays和collections进行操作。比如,使用Arrays.sort去排序一个array,Arrays.binarySearch在排好序的array中查找一个值。

尽管上面的Fibonacci实现中有一个用到了cache(基于sparse array),那个cache仅仅是临时的,当计算完成后马上变得可回收。可以使用一个LruCache去保存最终结果,如Listing 1-13所示。

Listing 1-13 使用LruCache保存Fibonacci序列值

int maxSize = 4*8*1024*1024;  // 32M
LruCache<Integer, BigInteger> cache = new LruCache<Integer, BigInteger>(maxSize) {
    protected int sizeOf(Integer key, BigInteger value) {
        return value.bitLength();  // 对象大小的近似值,以位为单位
    }
};
...
int n = 100;
BigInteger fN = cache.get(n);
if (fN == null) {
    fN = Fibonacci.computeRecursivelyWithCache(n);
    cache.put(n, fN);
}

任何时候你需要选择一个数据结构去解决问题,都要可以缩小选择到几类,因为每个类通常针对一个特定的目的优化或者提供一个特别的服务。比如,如果你不需要操作同步,可以选择ArrayList而不是Vector。当然,你可能经常创建自己的数据结构类,从头开始创建(继承object)或者继承一个现存的类。

NOTE:你能够解释为什么在Listing 1-11中,LruCache为什么不是computeRecursivelyWithCache一个好的选择么?

如果你使用的数据结构依赖于hashing(比如HashMap),并且key是你创建的类型,保证你重写了equal和hashCode方法。一个不好的hashCode实现可以轻易的消除使用hashing带来的好处。

TIP:参看http://d.android.com/reference/java/lang/Object.html,hashCode()的一个很好的实例。

尽管对许多的嵌入式应用开发者来说,在应用程序的不同部分把一个数据结构转换成另外一个并不常见。在有些情况下,性能的提升可以很容易的超过转换的开销,因为有更好的算法可以应用。一个常见的例子的是collection转换为array,很可能是已经排过序的。这样的一个转换显然需要内存,因为需要创建一个新对象。在内存受限的设备上,这样的内存分配不是经常可行的,会产生OutOfMemoryError异常。Java语言规范指出两件事:

(1) Error类和它的子类是普通的应用程序通常不预期可恢复的异常
(2) 成熟的应用期望可以捕获和从Error异常恢复

如果内存分配只是优化的一部分,而你作为一个熟练的应用开发者,可以提供一个fallback机制(比如,一个算法,尽管慢一些,使用最原始的数据结构),捕获OutOfMemoryError异常,这样允许兼容更多的设备。这些可选的优化使你的代码更难维护,但是可以让你达到更大的目标。

NOTE:与直觉不同的是,不是所有的异常都是Exception的子类。所有的异常是Throwable的子类(Exception和Error是它的直接子类)。

总而言之,你要对java.util和android.util两个包非常熟悉,因为它们是几乎所有组件依赖的工具箱。每当一个新的安卓版本发布的时候,你需要尤其关注这些包的变动(添加的类、改变的类),可以参考http://d.android.com/sdk。更多的数据结构在java.util.concurrent中讨论,它们将在第五章涉及到。

下载方式:https://renmaiwang.cn/s/t0445 在时序发生器设计实验中,如何达成T4至T1的生成? 时序发生器的构建可以通过运用一个4位循环移位寄存器来达成T4至T1的输出。 具体而言:- **CLR(清除)**: 作为全局清零信号,当CLR呈现低电平状态时,所有输出(涵盖T1至T4)皆会被清除。 - **STOP**: 在T4脉冲的下降沿时刻,若STOP信号处于低电平状态,则T1至T4会被重置。 - **启动流程**: 当启动信号START处于高电平,并且STOP为高电平时,移位寄存器将在每个时钟的上升沿向左移动一位。 移位寄存器的输出端对应了T4、T3、T2、T1。 #### 2. 时序发生器如何调控T1至T4的波形形态? 时序发生器通过以下几个信号调控T1至T4的波形形态:- **CLR**: 当CLR处于低电平状态时,所有输出均会被清零。 - **STOP**: 若STOP信号为低电平,且在T4脉冲的下降沿时刻,所有输出同样会被清零。 - **START**: 在START信号有效(通常为高电平),并且STOP为高电平时,移位寄存器启动,从而产生环形脉冲输出。 ### 微程序控制器实验#### 3. 微程序控制器实验中的四条机器指令及其对应的微程序段指定的机器指令及其关联的微程序段如下:- **NOP**: 00- **R0->B**: 04- **A+B->R0**: 05- **P<1>**: 30- **IN->R0**: 32- **R0->OUT**: 33- **HLT**: 35#### 4. 微程序段中的微操作/微命令序列针对每条微指令,其对应的微操作或微命令序列如下:- **IN->R0**: 输入(IN)单元的数据被...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值