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

Java int 轉 String 效能深度對比:+"" vs valueOf vs toString 源碼級分析

     編輯:Java 綜合教學

Java int 轉 String 效能深度對比:+"" vs valueOf vs toString 源碼級分析

Java 中 `int` 轉 `String` 有三種常見寫法:i + ""、String.valueOf(i)、Integer.toString(i)。實測 10 萬次循環,耗時對比:

i + ""              : 257 ms
String.valueOf(i)   : 140 ms
Integer.toString(i) : 159 ms

結論:+ "" 明顯較慢,後兩者接近。為什麼?深入 JDK 源碼揭秘。

源碼追蹤

String.valueOf(int)

public static String valueOf(int i) {
    return Integer.toString(i);  // 直接委託
}

Integer.toString(int)

public static String toString(int i) {
    return Integer.toString(i, 10);  // 基數 10
}

// 核心實現
static String toString(int i, int radix) {
    if (radix == 10) return toString(i);  // 內部調用
    // ... 其他進制
}

// 最終落點:Integer.toString(int) -> Integer.toUnsignedString0(i)
static String toString(int i) {
    return toUnsignedString0(i);
}

實際核心邏輯在 Integer.toUnsignedString0(JDK 8+)或 Integer.getChars(舊版),採用 **查表法 + 分治算法** 高效轉換。

核心算法細節(JDK 8 Integer.toUnsignedString0)

  1. 小數快速路徑 (0~99):預計算兩位數字符串陣列 DIGITS/TENS/ONES,O(1) 直接查表返回。
  2. 大數分治:
    - 每次除以 100,利用魔數 0x51EB851F 乘法代替除法(q = (i * 0x51EB851F) >>> 37),餘數 r = i - 100*q。
    - 餘數 r (0~99) 再查表獲取兩位字符。
    - 循環直到剩餘 < 100,最後處理最高位。
    - 魔數來源:《Hacker's Delight》第 10-8 節「除以常數優化」。
  3. 負數處理:先取絕對值,若為 Integer.MIN_VALUE 直接返回 "-2147483648",否則加負號前綴。

為何 i + "" 較慢?

編譯器將 i + "" 轉為:

new StringBuilder().append("").append(i).toString()

額外開銷:
1. `new StringBuilder()` 物件分配。
2. `append("")` 無意義操作。
3. `append(int)` 內部仍調用 `Integer.getChars`(同核心算法),但多了 `StringBuilder` 擴容、複製、`toString()` 新建 `String` 物件。
4. JIT 雖可優化標量替換,但不如靜態方法直接返回字符串穩定。

驗證:小數 (i=10) 效能差距更大

i + ""              : 199 ms
String.valueOf(i)   : 7 ms
Integer.toString(i) : 6 ms

小數命中快速查表路徑,+ "" 的物件分配開銷佔比更高。

最佳實踐建議

  1. 優先使用 Integer.toString(i) 或 String.valueOf(i):語意清晰、零額外分配、效能最優。
  2. 避免 i + "":雖然寫法簡短,但在高頻調用、日誌拼接、序列化等熱點路徑有可測量開銷。
  3. 格式化需求用 String.format / DecimalFormat:如千分位、補零等複雜格式。

延伸:其他基本類型同理

  • Long.toString(l)、Double.toString(d) 等均提供高效靜態方法。
  • Boolean.toString(b) 返回共享常量 "true"/"false",極快。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved