Android应用程序运行的性能设计
作者:网络转载 发布时间:[ 2013/9/5 13:52:49 ] 推荐标签:
zero()是当中慢的,因为对于这个遍历中的历次迭代,JIT不能优化获取数组长度的开销。
One()稍快,将所有东西都放进局部变量中,避免了查找。但仅只有数组长度促使了性能的改善。
Two()是在无JIT的设备上运行快的,对于有JIT的设备则和one()不分上下。他采用了JDK1.5中的改进for循环语法。
结论:优先采用改进的for循环,但在性能要求苛刻的ArrayList迭代中考虑采用手写计数循环。
9.在私有内部内中,考虑用包访问权限替代私有访问权限
考虑下面的定义:
Java代码
publicclassFoo{
privateclassInner{
voidstuff(){
Foo.this.doStuff(Foo.this.mValue);
}
}
privateintmValue;
publicvoidrun(){
Innerin=newInner();
mValue=27;
in.stuff();
}
privatevoiddoStuff(intvalue){
System.out.println("Valueis"+value);
}
}
需要注意的关键是:我们定义的一个私有内部类(Foo$Inner)直接访问外部类中的一个私有方法和私有变量。这是合法的,代码也会打印出预期的Valueis27。
但问题是虚拟机认为从Foo$Inner中直接访问Foo的私有成员是非法的,因为他们是两个不同的类,尽管Java语言允许内部类访问外部类的私有成员,编译器生成几个综合方法来桥接这些间隙。
Java代码
/*package*/staticintFoo.access$100(Foofoo){
returnfoo.mValue;
}
/*package*/staticvoidFoo.access$200(Foofoo,intvalue){
foo.doStuff(value);
}
内部类会在外部类中任何需要访问mValue字段或者doStuff方法的地方调用这些静态方法。这意味着这些代码将直接存取成员变量归结为通过存取器方法访问。之前提到存取器访问如何比直接访问慢,这例子说明,某些语言约定导致了不可见的性能问题。
如果你在高性能的Hotspot中使用这些代码,可以通过声明被内部类访问的字段和成员为包访问权限,而非私有。不幸的是这意味着这些字段会被其他处于同一个包中的类访问,因此在公共API中不宜采用。
10.合理利用浮点数
通常的经验是,在Android设备中,浮点数会比整型慢两倍,在缺少FPU,或是JIT的G1以及有FPU和JIT的NexusOne中确实如此(两种设备间算数运算的速度差大约是10倍).
速度术语中,在现代硬件上,float和double之间并没有不同。更广泛的讲,double大约2倍大。在没有存储空间问题的桌面机器中,double的优先级高于float。
但即使是整型,有些芯片拥有硬件乘法,却缺少除法。这种情况下,整型除法和求模运算是通过软件实现的,考虑下当你设计Hash表,或是做大量的算术。
11.了解并使用类库
除了通常的那些有限选择类库代码而非自己的原因外,考虑到系统空闲时用手写的汇编程序来替代类库方法,这可能比JIT中能生成的好的等效Java代码还要好。典型的例子是String.indexOf,Dalvik用内部内联来替代。同样的,System.arraycopy方法比NexusOne中有JIT的自行编码循环快9倍.
12.合理利用本地方法
本地方法并不是一定比Java高效,至少,Java和native之间过渡的关联是有消耗的。而JIT并不能越过这个界限进行优化。当你分配本地资源时(本地堆上的内存,文件说明符等),往往很难实时的回收这些资源。同时你也需要在各个结构中编译你的代码,而非依赖JIT。甚至可能需要针对相同的架构来编译出不同版本:针对ARM处理器的GI编译的本地代码,并不能充分利用NexusOne上的ARM,而针对NexusOne上ARM编译的本地代码不能在G1的ARM上运行。
当存在有你想部署到Android上的本地代码库时,本地代码显得尤为有用,而非为了Java应用程序的提速。
结语
后:通常权衡的,先确定存在问题,再进行优化。确认你知道当前的性能,否则无法衡量你进行尝试所得到的提升。
这份文档中的每个主张都有基准测试作为支持。你可以在code.google.com的dalvik项目中找到基准测试的代码。
基准测试是用CaliperJava微基准测试框架构建的。微基准测试很难走对,Caliper帮你完成了其中的困难工作。即使当你察觉某些情况的测试结果并非你所想象的那样(虚拟机总是在优化你的代码那)。我们强烈推荐你用Caliper来运行你自己的微基准测试。
同时你也会发现Traceview对分析很有用,但必须了解,他目前是不支持JIT的,这可能导致那些在JIT上可以胜出的代码超时。特别重要的,当根据Taceview的数据作出更改后,确保代码在没有Traceview时,确实跑的快了。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11