Android程序设计中的性能提升

Android SDK docs中有一部分,叫做Designing for Performance,这里将主要内容写一下,详情请看SDK docs。

  • 不要创建不需要的对象
  1. 如果有一个方法会返回一个String,并且一定会添加到一个StringBuffer中,那么最好改变为一个可以直接向StringBuffer添加的实现,而不是创建一个不会再被使用的String对象。
  2. 当从输入中提取一个字符串时,使用String.substring()方法,这样也会创建一个新的String对象,但是会共享原始数据的char[]从而减少了空间的分配。这样做的坏处是:如果你只会用到原始数据的一小部分,系统还是会保存整个数据。(这一条不知道理解的对不对,原话是:The trade-off being that if you're only using a small part of the original input, you'll be keeping it all around in memory anyway if you go this route.
  3. 一个int[]比 Integer[]要好很多,两个int[](一个保存值一个保存维的大小)比一个(int, int)数组要好很多。这对于所有的基本类型都适用。
  4. 如果要设计一个数组存放(ClassA, ClassB)时,那么不如使用ClassA[],ClassB[]好。当然,当为了设计一个API时,还是使用一个数组好。但是,如果是在自己的内部代码中使用,还是使用两个数组好。
  • 尽量使用static而不是virtual
  1. 如果不需要在方法中访问对象的成员变量,那么将这个方法声明为static,这样有15%~20%的性能提升。
  • 尽量不使用本类中的getter setter
  1. 在C++这类语言中使用getter setter时,编译器可以以内联方式调用,但是在java中,这种调用会带来较大的开销。在公共接口中这样做依然合理,但是在同一个类中不要使用这用方式访问,没有JIT支持时,直接访问类成员比调用一个这种getter setter方法要快三倍,有JIT支持时,要快七倍。
  • 对于常量,使用static final来修饰
  1. 在类中有常量如下声明:
static int intVal = 42;
static String strVal = "Hello, world!";
编译器会生成一个<clinit>的方法,当类被第一次调用来初始化这两个变量。当程序中使用这两个变量时,会使用field looup(成员查找)方式访问。
加上final后:
static final int intVal = 42;
static final String strVal = "Hello, world!";
编译器不会在生成<clinit>方法,使用intVal的时候会直接用42替换,使用strVal的地方会使用开销很低的字符串常量而不用进行耗时成员查找。

注意:这种优化只适用于基本类型和String类型的常量。但是将常量声明为static final是一个好的习惯

  • 使用加强版for循环
  1. 对于collection,for(Object o: Collection)这种形式会自动调用hasNext()和next(),但是对于ArrayList,传统的for循环会比这种写法快三倍,因此对于collection推荐使用for(Object o: Collection),对于ArrayList推荐使用传统for循环。
  • 当内部类要访问外部类私有成员变量时,考虑将内部类实现成单独的类
  1. 在内部类中访问外部类的私有成员变量时,虽然编译能通过,但是jvm仍然认为这是两个类,直接访问私有成员是非法的,所以编译器会在外部类中生成对应的get\set的包范围的静态方法共这个内部类使用,所以这里就多了一层方法调用。如果在性能关键点使用这种方式,就不如将内部类要访问的成员变量设置为包可见的。当然这不适用于公共API。
  • 谨慎使用浮点类型
  1. 在Android设备中,浮点类型计算比整型计算大约慢一倍,而float和double之间的速度是一样的,在pc中double类型精度更高,所有更应该倾向于使用double。
  • 使用已有的库中的方法
  1. 相对于自己写代码实现功能,最好使用已有库中的方法,比如String.indexOf()方法,Dalvik会使用一个内联的实现,同样的,复制数组时,System.arraycopy()方法比手写的循环方法快九倍。
  • 谨慎使用本地方法
  1. 使用JNI不是提升性能的必要条件,因为java与本地代码传输数据也是有开销的,同时,本地代码不会被JIT优化。JNI的常用场景是将一个已有的库应用到工程中,而不是加速java程序的运行。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值