字符串拼接是日常開發高頻操作,但 +、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 ms | 8956 ms | 基準 (1x) |
| StringBuffer | 3 ms | 5 ms | ~2000x 快 |
| StringBuilder | 2 ms | 3 ms | ~3000x 快 |
String 是不可變對象。每次 s += "ss" 實際上是:
StringBuilder(或舊版 StringBuffer)append() 拼接toString() 生成新 StringString 變為垃圾等待 GC10 萬次循環 = 10 萬次對象創建 + 10 萬次字符數組複製 + GC 壓力,性能雪崩。
| 特性 | StringBuffer | StringBuilder |
|---|---|---|
| 線程安全 | 同步方法,線程安全 | 非同步,線程不安全 |
| 性能 | 稍慢(鎖開銷) | 極快(無鎖) |
| 適用場景 | 多線程共享緩衝區 | 單線程 / 局部變量 |