优化技术之初级优化

2013-06-29

初级优化

我们都知道可供程序利用的资源(内存,CPU时间,网络宽带等)是有限的,优化的目的就是让程序用尽可能少的资源完成预定的任务。

优化通常包括两方面的内容:减小代码的体积,提高代码的运行效率。

在Java程序中,性能问题的大部分原因并不在于Java语言,而是在于程序本身。养成好的编程习惯非常重要,比如正确地、巧妙地运用java.lang.String类和java.util.Vector类,它能够显著地提高程序的性能。

1. 尽量指定类的final修饰符。带有final修饰符的类是不可派生的,且该类所有的方法都是final类型。Java编译器会寻找机会内联所有的final方法,使性能平均提高50%。

2. 尽量重用对象。特别是String对象的使用中,出现字符串连接情况时应该使用StringBuffer。

3. 尽量使用局部变量。调用方法时传递的参数以及在方法中创建的临时变量都保存在栈Stack中,速度较快。其他变量,如静态变量、实例变量等,都在堆Heap中创建,速度较慢。

4. 不要重复初始化变量。调用类的构造方法时,Java会把静态变量、临时变量初始化。

5. 在Java + Oracle应用开发中,Java中内嵌的SQL语句尽量使用大写的形式,以减轻Oracle解析器的解析负担。

6. Java编程过程中,进行数据库操作、I/O流操作时务必小心,在使用完毕后,及时关闭以释放资源。因为对这些大对象的操作会造成系统大的开销,稍有不慎,会导致严重后果。

7. 保证过期对象的及时回收具有重要意义。JVM回收垃圾的条件是:对象不再被引用,然而,JVM的GC并非十分地机智,即使对象满足了垃圾回收的条件也不一定会被立即回收。所以,在对象使用完毕后,建议设置成null。

8. 在使用同步机制时,应尽量使用方法同步代替代码块同步。

9. 尽量减少对变量的重复计算。

for(int i=0;i<list.size();i++) 应替换为:

for(int i=0, int len=list.size();i<len;i++)

10. 尽量采用Lazy Loading策略,在需要的时候才开始创建。

11. 慎用异常,异常对性能不利。异常只能用于处理错误,不应该用来控制程序流程。

12. 不要在循环中使用try/catch语句,应把其放置在最外层。

13. StringBuffer的使用。StringBuffer表示了可变的、可写的字符串,有三个构造方法:

StringBuffer() // 默认分配16个字符的空间

StringBuffer(int size) // 分配size个字符的空间

StringBuffer(String str) // 分配16 + str.length()个字符空间

使用一个合适的size来创建StringBuffer对象,永远都是一个最佳的建议。

14. 合理的使用Java.util.Vector类。一个Vector就是一个对象数组,它的元素可以通过证书形式的索引访问。Vector的使用有以下几个区别:

// 增加元素

Object obj = new Object();

Vector v = new Vector(10000);

for(int i=0;i<10000;i++) {

  v.add(0, obj); // 此句效率相对较低,尽量使用:v.add(obj);

}

// 删除元素

for(int i=0;i<10000;i++) {

  v.remove(0); // 词句效率相对较低,尽量使用:v.remove(v.size()-1);且将v.size()提出来

}

// 删除全部元素,尽量使用:

v.removeAllElements();

15. 当复制大量数据时,尽量使用System.arrayCopy()。

16. 代码重构,增强代码的可读性。

17. 尽量不用new关键字创建类的实例。

public static Credit getNewCredit() {

  return new Credit();

}

尽量使用:

public static Credit baseCredit = new Credit();

public static Credit getNewCredit() {

  return (Credit) baseCredit.clone();

}

18. 乘法和除法。

for(val = 0; val < 10000; val += 5) {

  alterX = val * 8;

  myResult = val * 2;

}

可以使用以下替换,但不是那么好理解,最后加注释

for(val = 0; val < 10000; val += 5) {

  alterX = val << 3;

  myResult = val << 1;

}

19. 尽量不要将数组声明为:

public static final

20. HashMap的遍历效率。

Map<String, String[]> map = new HashMap<String, String[]>();

Set<String> keys = map.keySet();

for(String key : keys) {

  String[] values = map.get(key);

}

尽量使用:

for(Entry<String, String[]> entry : map.entrySet()) {

  String key = entry.getKey();

  String[] values = entry.getValue(key);

}

21. array, [], 最高效,但是其容量固定且无法动态改变;ArrayList,容量可动态增长,但牺牲效率。

22. 尽量使用HashMap, ArrayList,而不是HashTable, Vector,因为后者使用同步机制,导致性能的开销。

23. StringBuffer线程安全,StringBuilder支持所有所有相同的操作,但由于它不执行同步,所以速度更快。为了获取更好的性能,在构造StringBuffer或StringBuilder时应尽可能指定容量。如果你操作的字符串长度不超过16就不用了。除非你能确定系统的瓶颈在StringBuffer上,并且确定你的模块不会运行在多线程模式下,否则还是用StringBuffer,因为StringBuilder只能获取10%~15%的性能提升,但非线程安全的。

你可能感兴趣的:(优化)