Java程序性能優化(2)

  八、如果只是查找單個字符的話,用charAt()代替startsWith()

  用一個字符作爲參數調用startsWith()也會工作的很好,但從性能角度上來看,調用用String API無疑是錯誤的!

  例子:

  public class PCTS {

  private void method(String s) {

  if (s.startsWith("a")) { // violation

  // ...

  }

  }

  }

  更正

  將'startsWith()' 替換成'charAt()'.

  public class PCTS {

  private void method(String s) {

  if ('a' == s.charAt(0)) {

  // ...

  }

  }

  }

  參考資料:

  Dov Bulka, "Java Performance and Scalability Volume 1: Server-Side Programming

  Techniques"  Addison Wesley, ISBN: 0-201-70429-3

  九、使用移位操作來代替'a / b'操作

  "/"是一個很“昂貴”的操作,使用移位操作將會更快更有效。

  例子:

  public class SDIV {

  public static final int NUM = 16;

  public void calculate(int a) {

  int div = a / 4;            // should be replaced with "a >> 2".

  int div2 = a / 8;         // should be replaced with "a >> 3".

  int temp = a / 3;

  }

  }

  更正:

  public class SDIV {

  public static final int NUM = 16;

  public void calculate(int a) {

  int div = a >> 2;

  int div2 = a >> 3;

  int temp = a / 3;       // 不能轉換成位移操作

  }

  }

  十、使用移位操作代替'a * b'

  同上。

  [i]但我個人認爲,除非是在一個非常大的循環內,性能非常重要,而且你很清楚你自己在做什麼,方可使用這種方法。否則提高性能所帶來的程序晚讀性的降低將是不合算的。

  例子:

  public class SMUL {

  public void calculate(int a) {

  int mul = a * 4;            // should be replaced with "a << 2".

  int mul2 = 8 * a;         // should be replaced with "a << 3".

  int temp = a * 3;

  }

  }

  更正:

  package OPT;

  public class SMUL {

  public void calculate(int a) {

  int mul = a << 2;

  int mul2 = a << 3;

  int temp = a * 3;       // 不能轉換

  }

  }


  十一、在字符串相加的時候,使用 ' ' 代替 " ",如果該字符串只有一個字符的話

  例子:

  public class STR {

  public void method(String s) {

  String string = s + "d"  // violation.

  string = "abc" + "d"      // violation.

  }

  }

  更正:

  將一個字符的字符串替換成' '

  public class STR {

  public void method(String s) {

  String string = s + 'd'

  string = "abc" + 'd'

  }

  }

  十二、不要在循環中調用synchronized(同步)方法

  方法的同步需要消耗相當大的資料,在一個循環中調用它絕對不是一個好主意。

  例子:

  import java.util.Vector;

  public class SYN {

  public synchronized void method (Object o) {

  }

  private void test () {

  for (int i = 0; i < vector.size(); i++) {

  method (vector.elementAt(i));    // violation

  }

  }

  private Vector vector = new Vector (5, 5);

  }

  更正:

  不要在循環體中調用同步方法,如果必須同步的話,推薦以下方式:

  import java.util.Vector;

  public class SYN {

  public void method (Object o) {

  }

  private void test () {

  synchronized{//在一個同步塊中執行非同步方法

  for (int i = 0; i < vector.size(); i++) {

  method (vector.elementAt(i));

  }

  }

  }

  private Vector vector = new Vector (5, 5);

  }

  十三、將try/catch塊移出循環

  把try/catch塊放入循環體內,會極大的影響性能,如果編譯JIT被關閉或者你所使用的是一個不帶JIT的JVM,性能會將下降21%之多!

  例子:

  import java.io.FileInputStream;

  public class TRY {

  void method (FileInputStream fis) {

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

  try {                                      // violation

  _sum += fis.read();

  } catch (Exception e) {}

  }

  }

  private int _sum;

  }

  更正:

  將try/catch塊移出循環

  void method (FileInputStream fis) {

  try {

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

  _sum += fis.read();

  }

  } catch (Exception e) {}

  }

  參考資料:

  Peter Haggar: "Practical Java - Programming Language Guide".

  Addison Wesley, 2000, pp.81 – 83

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章