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

第四章 有效使用内存

应用程序花费显著的时间处理内存中的数据。很多开发者意识到在手机或者平板这样的设备上使用尽量少的内存,但是不是所有人都意识到了内存使用在性能上的影响。在本章,你将学习到如何选择合适的数据类型和怎样在内存中安排你的数据可以提升你的应用程序的性能。同样的,我们将review一个基本的但是经常忽略的Java Feature:使用GC管理内存和引用。

内存中的一个字

不管一个应用是怎么给出的,它经常会要求升级。
安卓设备(手机或者平板)和一个传统的计算机有两个很大的不同:
(1) 物理内存的数量
(2) 是否可以去做虚拟内存转换

通常,现在的计算机有几个G的RAM(几乎没有少于1G的),然而,安卓设备最大的RAM经常为512M。更加雪上加霜的是,计算机使用交换技术,而安卓设备没有,这个机制可以给系统和应用更多内存的错觉。比如,一个应用可以寻址4G的内存,尽管系统仅有256M的RAM。安卓应用通常没有这么奢侈,需要更加小心对待你的应用将使用多少内存。

NOTE:你可以在安卓市场上找到允许交换的应用,但是他们需要Root权限和一个不同的Linux内核。需要假设你的应用将跑在没有交换兼容的安卓设备上。

Java语言定义了大多数的原子类型的大小,如Table 4-1所示,和他们相匹配的native类型。如果你原来熟悉C/C++代码,你需要在两个事情上额外注意:
(1) Java的char是16位的(UTF-16)
(2) Java的long是64位的(C的long通常是32位的,C的long long通常是64位)

Table 4-1 Java原子类型


一个好的经验法则是使用尽量少的内存,通常直觉安卓设备和应用有着有限的内存。为了减少OutOfMemoryError异常的风险,使用更少的内存同样可以增加性能。
性能主要依赖于三个事情:
(1) CPU如何操作一个具体的数据类型
(2) 空间是如何被利用去存储数据和指令的
(3) 数据在内存中如何排列的
我们将覆盖每一项,包含native代码和Java代码,测试执行次数,比较几个简单的提升性能算法的实现。

数据类型

CPU怎么操作一个具体的数据类型,你已经在第二章computeIterativelyFaster()的native代码有了概念,它使用两个加指令去使两个64位整数相加,如Listing 4-1所示。

Listing 4-1 使两个64位整数相加


因为ARM寄存器是32位宽,两个64位整数相加需要2个指令;最低的32位整数存储在一个寄存器中(r4),高位的32位存储在另外一个寄存器中(r5)。2个32位的数值相加需要一个指令。
现在让我们考虑传统的C函数,在Listing 4-2中,只是简单的返回2个32位参数的和。

Listing 4-2 两个值的和

int32_t add_32_32 (int32_t value1, int32_t value2)
{
    return value1 + value2;
}
这个函数的汇编代码在Listing 4-3给出。

Listing 4-3 汇编代码



就像期望的,两个数值相加仅需要一个指令(bx lr等同于return)。我们现在可以创建非常像add_32_32这样的新函数,但是value1和value2的类型不同。比如, add_16_16把2个int16_t的数值相加,如Listing 4-4所示,add_16_32把int16_t值和int32_t值相加,如Listing 4-5所示。

Listing 4-4 C和汇编的add_16_16



Listing 4-5 add_16_32的C和汇编代码




你可以看到2个16为的值相加为了转换结果到32位需要一个额外的指令。
Listing 4-6给出5个更多的函数,不同的数据类型重复基本的同样的算法。
Listing 4-6 更多的汇编代码



NOTE: 产生的本地代码可能和这里展示的不同,因为很多依赖于加法的上下文。(inline代码可能看起来不同,因为编译器可能记录指令或者改变寄存器分配)

就像你可以看到的,使用一个更小的类型,并不总是可以提升性能,因为它可能实际需要更多的指令,如Listing 4-4展示的。同时,如果add_16_16调用带有两个32位的参数,这两个值将在被实际调用前首先被转换为16位的值,如Listing 4-7所示。再一次的,sxth指令通过执行sign extend操作来转换32位的数据到16位。

Listing 4-7 使用两个32位值调用add_16_16


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值