1. 先把焦点放到设计、数据结构和算法上。
2. 不要依赖编译期优化技术。
编译期优化是指:在调试阶段,把编译优化给关闭掉,当调试完毕后,再打开编译优化让编译优化来选择最便捷的代码,这样程序运行性能就很好。Java编译器对产生优化后的bytecode不是很启作用。
3. 理解运行期(runtime)代码优化技术
4. 要使字符串拼接结合,请尽量使用StringBuffer,而不是String。
String表示建立后的对象,其字符序列不能够再被修改了。
StringBuffer表示建立后的对象,其中的字符序列的值是可以变化的。
5. 将创建对象的成本降到最小。
创建对象所有做到事情,顺序如下:
1.从heap 之中分配内存,用以存放全部的instance 变量以及这个对象连同其superclasses 的实现专届数据(implementation-specific data)。所谓[实现专属数据]包括指向“class and method data”的指针。
2.对象的instance 变量被初始化为其相应的缺省值。
3.调用most derived class(最深层派生类)的构造函数(constructor)。构造函数做的第一件事就是调用superclass 的构造函数。这个程序一直反复持续到java.1ang.object 构造函数被调用为止。一定要记住,java.1ang.object 是一切Java 对象的base class。
4.在构造函数本体执行之前,所有instance 变量的初始值设定(initializers) 和初始化区段(initialization blocks)先获得执行,然后才执行构造函数本体。于是base class 的构造函数最先执行,most derived class 的构造函数最后执行。这使得任何class 的构造函数都能放心大胆地使用其任何superclasses 的instance 变量。
创建对象的过程,举例如下:
public class Light {
private int val;
private boolean hasData = true;
public Light(int a) {
val = a;
}
public static void main(String[] args) {
Light lgt = new Light(2);
}
}
Light 对象的建立步骤如下:
1.从heap 分配内存,用来存放Light class 的instance 变量,以及一份[实现专属数据]。
2.此class 的instance 变量val 和hasDate,被初始化为相应缺省值。Val 被赋值为0,这是Int 的缺省值,hasDate 被韧始化为缺省值fa1se。
3.调用Light 构造函数,传入数值5。
4.调用Light 构造函数调用其superclass(本例为j ava.1ang.object)的构造函数。
5.一旦java.1ang.object 构造函数返回,Light构造函数执行其instance 变量的初值设定工作。此时将hasData 赋值为true。
6.将val 赋值为5,而后Light 构造函数结束。
7.object reference lgt 指向head 中刚刚建立完成的Light对象。
以下class特征会增加创建对象的成本:
1. 构造函数含有大量代码;
2. 内含数量众多的对象;
3. 继承层次太深。
6. 慎防未用上的对象
在需要的时候才创建对象。
7.将同步化(synchronization)降至最低
一般情况下,请不要使用synchronized,因为会降低性能。如果不得已的话,请优先将synchronized加在函数上,然后再考虑是否加在函数内部。因为如果你在函数本体中使用synchronized,就会产生操作代码monitorenter 和Moniterexit 的bytecode,以及为了处理异常而附加的代码。
8. 尽可能使用stack变量。
9. 使用static、final 和private 函数以促成inlining(内联)。以函数体替换掉函数调用,性能会增加。一般是小型函数被促成inlining。
10. instance 变量的初始化一次就好.对象的instance变量的默认初始化,在构造方法执行前已经执行力次,所以不需要造次执行。只有class 的static 变量和instance 变量才有缺省值,局部变量是没有缺省值。
11.使用原生态数据类型代码更快更小。
不要使用Enumeration 或Iterator 来遍历Vector。Java提供了以下方式来获取变量vector中的元素:
a.Interaor遍历器
b. ListInterator遍历器(只针对List的)
c. Enumeration(枚举器)
d. Get函数
12.使用System.arraycopy来复制数组. System.arraycopy()是以本机函数(native method)实现的,因此它的执行速度更快。
13.优先使用数组,然后再考虑使用Vector和ArrayList。Vector和ArrayList底层都是以数组来实现的,而Vector调用的时候都是同步的,并且都要调用其他函数,所以在数组、Vector、ArrayList这三者中,Vector效率最慢。
14.尽可能复用对象。
15.使用缓式评估(延迟求值,lazy evaluation),是一项与语言无关的技术,它会延缓计算,直到不能再拖延为止。工作的推迟当然不会带来性能的提升,但如果被推迟的计算后来不再需要,从而不需执行的话,性能就提升了。也就是说免除了非必要的工作。
16. 以手工的方式将代码优化。Javap –c 便可以反编译.class文件。
Java –c 类(去掉了.class后缀)> test.txt(存储文件),将会产生bytecode。
17. 编译为本机代码。将java 源码编译为目标平台上的本机二进制码(native binary code)。。这种做法并不是把java 源码编译为中介的bytecode 形式.而是直接编译为本机机器指令(native machine instructions)。这样做的好处在于,你不再需要为[运行期间将bytecode 转换为native code 付出额外代价,因而往往获得更快捷的代码。缺点是通常会丢失[平台可移植性]——尽管这或许不是你在意的。面对这个问题,至少有一种解决方案,既不会失去平台可移植性,又享有本机二进制码(native binary code)在执行速度上的优势。