首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 入門:String 與 Vector 效能優化實戰

     編輯:Java 程式設計入門

前言:易用性的雙面刃

Java 降低了開發門檻,但若缺乏良好的編碼習慣,效能往往不如 C++。大多數效能問題源於程式碼本身而非語言。本文聚焦兩個高頻使用且易被濫用的類別:java.lang.String 與 java.util.Vector,透過實例剖析優化技巧。

一、字串串接:String vs StringBuffer

常見誤區

String s1 = "Testing String";
String s2 = "Concatenation Performance";
String s3 = s1 + " " + s2; // 效率低?

編譯器實際會將其轉換為 StringBuffer(或 JDK 5+ 的 StringBuilder)操作,因此手動寫 StringBuffer 並不一定更快:

StringBuffer sb = new StringBuffer();
sb.append("Testing String");
sb.append(" ");
sb.append("Concatenation Performance");
String s3 = sb.toString();

關鍵在於「預分配容量」

StringBuffer() 預設容量僅 16 字元。當內容超過容量時,會觸發 expandCapacity(),內容複製開銷大。若能預估最終長度,指定初始容量可避免多次擴容:

// 最終約 40 字元,給 45 餘裕
StringBuffer sb = new StringBuffer(45);
sb.append("Testing String");
sb.append(" ");
sb.append("Concatenation Performance");
String s3 = sb.toString();

迴圈中串接:更明顯的差異

// 低效:每次迴圈建立新 StringBuffer 與 String
String s = "";
for (int i = 1; i < 10; i++) {
    s = s + "+" + i;
}

// 高效:複用單一 StringBuffer
StringBuffer sb = new StringBuffer();
for (int i = 1; i < 10; i++) {
    sb.append(i).append("+");
}
String s = sb.append("=").append(sum).toString();

前者每次迴圈產生兩個臨時物件,後者零臨時物件,效能差距隨迴圈次數線性放大。

二、Vector 使用陷阱與優化

插入位置影響效能

Vector 底層為陣列,add(0, obj) 會導致所有現有元素後移,若在迴圈中重複執行,時間複雜度達 O(n²):

Vector v = new Vector(100000);
for (int i = 0; i < 100000; i++) {
    v.add(0, obj); // 極慢:每次搬移所有元素
}

改用 add(obj) 尾端新增,無搬移開銷,快數個數量級:

for (int i = 0; i < 100000; i++) {
    v.add(obj); // 僅擴容時複製
}

刪除操作同理

  • remove(0):後續元素前移,慢。
  • remove(size()-1):尾端刪除,無搬移,快。
  • 清空整個 Vector:removeAllElements() 一次完成,避免迴圈開銷。

避免重複搜尋

// 低效:indexOf 與 remove 各搜尋一次
String s = "Hello";
int i = v.indexOf(s);
if (i != -1) v.remove(s); // remove 內部再搜尋

// 優化:直接用索引刪除
if (i != -1) v.remove(i);

// 最佳:直接 remove 物件,內部僅搜尋一次
v.remove(s);

迴圈中重複呼叫 size()

// 低效:每次迴圈呼叫 size()
for (int i = 0; i < v.size(); i++) { ... }

// 優化:將 size 存入區域變數
int size = v.size();
for (int i = 0; i < size; i++) { ... }

雖 size() 極簡單,但方法呼叫仍有堆疊幀開銷,迴圈次數大時差距可觀。

總結

  • String 串接:迴圈或大量串接時,預分配 StringBuffer/StringBuilder 容量。
  • Vector:優先尾端增刪、避免頭部操作、善用批次方法(removeAllElements)、迴圈邊界條件提取不變量。
  • 這些微優化累積起來,能顯著降低 GC 壓力與 CPU 週期消耗。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved