性能小诀窍——波斯沃斯决战的小失误,大毁灭

来源:互联网 发布:sqlserver 服务器ip 编辑:程序博客网 时间:2024/04/30 12:03

从本篇开始一直到 “ 如何避免 ANR”, 我们介绍 AndroidDeveloper Practices for Performance,我尽量用最精简易懂的方式将这些精要原则呈现给大家,详细的说明还请参考原文档:

 

http://developer.android.com/training/best-performance.html

 

先讲个故事轻松一下:

 

公元15世纪英国的国王查理三世与自己的反叛大臣亨利在波斯沃斯进行了一场大决战,由于查理三世的战马少了一颗马蹄钉,结果冲杀时战马受惊,将查理三世摔倒在地,士兵们见状四顾逃命,战争局势瞬间逆转,可怜的查理被俘后大呼:“我的国家就毁灭在一颗马蹄钉上面!”

 

本章谷歌给我们提出了一些在 android 开发中提升代码性能的很多细节注意点,每一条看起来都可有可无,可它们都是提升代码全局性能的马蹄钉。


1 不要创建多余对象

创建对象总会占用内存和CPU资源,应尽量避免创建不必要的对象,好比说:

  •  如果一个方法返回的 String 类型值总是连接到一个 StringBuffer 上,应修改其返回类型和实现,避免创建多余的临时对象;
  •  若总是只需要一个 sub String,则不要返回整个 String;
  • 一个 int 一维数组优于一个 Integer 数组,两个等长的一维数组优于一个 (int, int) 对象的一维数组,同样的情况适应于所有基本数据类型;
  • 一个 Foo[] 和一个 Bar[] 要优于一个单独的 (Foo, Bar)[]。

 

2 擅用静态方法

       如果你的方法无需访问对象中的任何域,请将其置为静态方法,其调用速度比一般方法快15% - 20%,另外,这也是个好的习惯,如果你能保持这样做,那么以后你看到这样的方法就能知道它不会更改对象的状态了。

 

3 使用 static final 修饰常量

       对于基本数据类型和 String 类型的常量,用 static final 来修饰比只用 static 修饰的效率要高,其它复杂数据类型的常量无此提升,但请尽量用 staticfinal 来修饰任何常量。

 

4 避免内部调用 Getters/Setters

在面向对象语言中使用 Getters/Setters 方法来获取和设置域的值是一个良好的习惯,但在 Android 中却很低效,除非在外部当中调用,你应该总是避免在类的内部使用 Getters/Setters,而应该直接访问这个域。

 

在没有 JIT 的情况下,直接访问域比Getters/Setters 快上3倍,而在有 JIT 时则快上7倍。

 

5 使用增强的 for 循环语法

       请看三种 for 循环:

      

1.    for (int i = 0; i < mArray.length; ++i)

2.    int len = localArray.length; for (int i = 0; i < len; ++i)

3.    for (Foo a : mArray)

 

for 循环速度从 1 到 3 依次加快。第 3 种为增强型 for 循环,除了 ArrayList 以外,我们默认都应该使用增强型 for 循环来遍历你的集合。

 

6 避免让私有内部类直接访问外部类的私有成员

       每当内部类访问外部类的私有成员时,编译器会为每一个外部私有成员额外创建一个静态访问方法,为了避免这种低效访问,应该将需要被内部类访问的外部私有成员访问权限修改为包权限(package-access,默认、公有、保护权限都为此权限),但应该注意到,这些成员同时暴露给了包内的所有其它类。

 

7 少用浮点数

       根据经验,在 android 设备中,浮点运算的速度比整型运算慢了2倍。

 

8 尽量用库方法

       好比说,在 JIT 编译环境下,System.arraycopy() 比纯手动数组拷贝要快上9倍。

 

9 慎用 Native 方法

       谷歌的工程师认为,native 方法并不一定比 Java 方法更高效,而且还会带来很多不必要的麻烦,除非有现成的 Native 代码库,且并非是为了提升速度,否则请慎用 Native 方法。

11 不要迷信性能教条

       这些性能小诀窍不是万能的,有时候需要更好的代码设计和可维护性可以牺牲部分性能,比如通常情况下,直接用 HashMap 的方法比其接口 Map 通过多态调用方法效率要高,可是我们知道接口的设计能给我们带来代码维护上的方便,而且引入 JIT 之后,这样的效率差可以忽略不计。

 

       总之,原则可以尽量遵守,但教条不能迷信。

 

12 多测试你的性能

       请参考Caliper 和 Traceview 性能测试工具。

 


原创粉丝点击