給定字符串,過濾非數字字符,要求耗時最小。測試環境:JDK 1.5.0_09,輸入 "D186783E36B721651E8AF96AB1C4000B",循環 1048576 次。
| 版本 | 核心優化 | 耗時(秒) | 提升倍數 |
|---|---|---|---|
| filter1 | String += char(最差) | 8.81-8.90 | 基準 |
| filter2 | StringBuffer.append() | 2.14-2.18 | ~4x |
| filter3 | 局部變量緩存 charAt/length | 1.48-1.52 | ~30% |
| filter4 | StringBuffer 預分配容量 | 1.33-1.39 | ~10% |
| filter5 | char[] 直接操作 + 最後 new String | 0.72-0.78 | ~50% (vs v4) |
String strNew = "";
for (int i=0; i<strOld.length(); i++) {
if ('0' <= strOld.charAt(i) && strOld.charAt(i) <= '9')
strNew += strOld.charAt(i); // 每次創建新 String 對象
}
int nLen = strOld.length();
char[] chArray = new char[nLen];
int nPos = 0;
for (int i=0; i<nLen; i++) {
char ch = strOld.charAt(i);
if ('0' <= ch && ch <= '9') {
chArray[nPos++] = ch;
}
}
return new String(chArray, 0, nPos);
new StringBuffer(nLen/10) 平衡空間filter1→5 耗時相差 **12 倍**,除 filter3 是減少調用外,其餘均在 **減少內存分配**。可見堆內存分配對性能影響之大——這正是上一篇「基本類型 vs 引用類型」強調的棧 vs 堆差異。