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

字符串拼接性能大比拼:String vs StringBuffer vs StringBuilder 實測分析

     編輯:Java 綜合教學

字符串拼接性能大比拼:String vs StringBuffer vs StringBuilder 實測分析

字符串拼接是日常開發高頻操作,但 +、StringBuffer、StringBuilder 三者性能差異究竟有多大?本文通過實測數據揭示真相,並給出選型建議。

實測代碼與環境

public static void testStringJoin() {
    long beg = System.currentTimeMillis();
    String s = null;
    for (int i = 0; i < 100000; i++) {
        s += "ss"; // String + 拼接
    }
    System.out.println("String + 耗時:" + (System.currentTimeMillis() - beg) + "ms");

    beg = System.currentTimeMillis();
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < 100000; i++) {
        sb.append("ss");
    }
    System.out.println("StringBuffer 耗時:" + (System.currentTimeMillis() - beg) + "ms");

    beg = System.currentTimeMillis();
    StringBuilder sbuilder = new StringBuilder();
    for (int i = 0; i < 100000; i++) {
        sbuilder.append("ss");
    }
    System.out.println("StringBuilder 耗時:" + (System.currentTimeMillis() - beg) + "ms");
}

實測結果(兩輪平均)

方式第1輪第2輪性能比
String +9102 ms8956 ms基準 (1x)
StringBuffer3 ms5 ms~2000x 快
StringBuilder2 ms3 ms~3000x 快

深度原理解析

為什麼 String + 這麼慢?

String 是不可變對象。每次 s += "ss" 實際上是:

  1. 創建新的 StringBuilder(或舊版 StringBuffer)
  2. 調用 append() 拼接
  3. 調用 toString() 生成新 String
  4. 原 String 變為垃圾等待 GC

10 萬次循環 = 10 萬次對象創建 + 10 萬次字符數組複製 + GC 壓力,性能雪崩。

StringBuffer vs StringBuilder 差異

實測中 StringBuilder 比 StringBuffer 快約 30%-50%,符合預期。

特殊優化:常量折疊

// 編譯期優化:直接合併為 "This is only a simple test"
String str = "This is only a" + " simple" + " test"; 

// 變量拼接:無法優化,走 StringBuilder
String a = "This is only a";
String b = " simple";
String c = " test";
String str2 = a + b + c; // 運行時拼接

選型最佳實踐

  1. 少量拼接、常量拼接:直接用 +,可讀性最好,編譯器優化
  2. 單線程大量拼接:StringBuilder 首選,性能最優
  3. 多線程共享拼接:StringBuffer 保證線程安全
  4. 日誌框架:使用佔位符 log.info("user={}, age={}", name, age) 避免不必要拼接

擴展:預估容量優化

// 預估最終長度約 200 萬字符,避免擴容複製
StringBuilder sb = new StringBuilder(2_000_000);
for (int i = 0; i < 100000; i++) sb.append("ss");

預分配內部字符數組,進一步消除擴容開銷。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性StringBufferStringBuilder
線程安全同步方法,線程安全非同步,線程不安全
性能稍慢(鎖開銷)極快(無鎖)
適用場景多線程共享緩衝區單線程 / 局部變量