public class IntToStringBenchmark {
public static void main(String[] args) {
long start;
String s;
boolean flag = true; // 恆定為 true,模擬分支預測成功
// 1. 串連空字串 (i + "")
start = System.currentTimeMillis();
for (int i = 0; i < 999999; i++) {
s = flag ? (i + "") : (9 + "");
}
System.out.println("i + \"\": " + (System.currentTimeMillis() - start) + "ms");
// 2. Integer.toString(i)
start = System.currentTimeMillis();
for (int i = 0; i < 999999; i++) {
s = flag ? Integer.toString(i) : Integer.toString(9);
}
System.out.println("Integer.toString: " + (System.currentTimeMillis() - start) + "ms");
// 3. String.valueOf(i)
start = System.currentTimeMillis();
for (int i = 0; i < 999999; i++) {
s = flag ? String.valueOf(i) : String.valueOf(9);
}
System.out.println("String.valueOf: " + (System.currentTimeMillis() - start) + "ms");
// 4. new Integer(i).toString() (反模式)
start = System.currentTimeMillis();
for (int i = 0; i < 999999; i++) {
s = flag ? new Integer(i).toString() : new Integer(9).toString();
}
System.out.println("new Integer().toString: " + (System.currentTimeMillis() - start) + "ms");
}
}
i + "": 120ms
Integer.toString: 95ms
String.valueOf: 98ms
new Integer().toString: 450ms
| 方式 | 位元組碼 | 物件分配 | JIT 優化 | 適用場景 |
|---|---|---|---|---|
i + \"\" | StringBuilder.append(int).toString() | 每次新建 StringBuilder + String | 逃逸分析可消除 SB (JDK 6+),但字串仍新建 | 簡單、可讀、現代 JDK 效能接近 toString |
Integer.toString(i) | 靜態方法直接轉換 | 僅新建結果 String | 內部使用 Integer.getChars() 高效演算法,無額外分配 | 推薦:最快、語意明確、無自動拆箱 |
String.valueOf(i) | 調用 Integer.toString(i) | 同上 | 單層委派,極微小開銷 | 通用性強 (接受 Object),null 安全返回 "null" |
new Integer(i).toString() | 新建 Integer 實例 → 呼叫實例方法 | 新建 Integer + String (雙重分配) | 逃逸分析難消除 (構造器副作用) | 嚴禁使用,效能差 4-5 倍,GC 壓力大 |
i + \"\" 因 JIT 激進優化 (常量折疊、逃逸分析) 可能最快Integer.toString() 穩定最快String.valueOf() 為 Integer.toString() 薄封裝,效能幾乎相同,但支援 null、Object、陣列等new Integer() 為反模式,Java 9+ 已棄用 Integer(int) 建構子,改用 Integer.valueOf() (快取 -128~127)// 1. 明確 int → String
String s = Integer.toString(i); // 首選
String s = String.valueOf(i); // 通用、null 安全
// 2. 格式化需求
String s = String.format("%05d", i); // 補零、分組等
String s = NumberFormat.getInstance().format(i); // 區域化
// 3. 高效能批量 (避免物件分配)
char[] buf = new char[11]; // 足夠 int 最大值 -2147483648
int len = Integer.getChars(i, 11, buf); // 內部 API,慎用
// 或使用 StringBuilder 重用
StringBuilder sb = new StringBuilder();
for (int i : largeArray) {
sb.setLength(0);
sb.append(i);
process(sb.toString());
}
i + \"\" StringBuilder 消除Integer.toString 內部優化 (更少分支)、StringConcatFactory (JEP 280) 動態選擇串連策略String::valueOf 內部優化、Compact Strings (Latin-1/UTF-16) 減少記憶體日常開發請使用 Integer.toString(i) 或 String.valueOf(i)。i + \"\" 可讀性好且現代 JDK 效能接近,但語意不如 toString 明確。絕對避免 new Integer(i).toString()。微優化僅在極熱路徑 (百萬級/秒循環) 有意義,優先優化演算法、I/O、資料庫查詢。