public class StringTest implements Clock { private int i = 0; public void testString() { String str = new String(); int j = i; for(; i < j + 40000; i++) { str += String.valueOf(i); } } public void testStringBuffer() { StringBuffer sb = new StringBuffer(); int j = i; for(; i < j + 40000; i++) { sb.append(String.valueOf(i)); } } public void testStringBuilder() { StringBuilder sb = new StringBuilder(); int j = i; for(; i < j + 40000; i++) { sb.append(String.valueOf(i)); } } public static void main(String[] args) { StringTest test = new StringTest(); test.stamp("String", test::testString); test.stamp("StringBuffer", test::testStringBuffer); test.stamp("StringBuilder", test::testStringBuilder); test.stamp("String", test::testString); test.stamp("StringBuffer", test::testStringBuffer); test.stamp("StringBuilder", test::testStringBuilder); test.stamp("String", test::testString); test.stamp("StringBuffer", test::testStringBuffer); test.stamp("StringBuilder", test::testStringBuilder); } }
簡單說明一下測試:java
環境,mac os 10.10.4, CPU 2.6 GHz Intel Core i5, Memory 8G;併發
每一個測試跑40000次,計時,並記錄結果;app
跑三次;ide
結果是:性能
It takes [110000000] nono seconds to process [String] It takes [5000000] nono seconds to process [StringBuffer] It takes [5000000] nono seconds to process [StringBuilder] It takes [654000000] nono seconds to process [String] It takes [4000000] nono seconds to process [StringBuffer] It takes [3000000] nono seconds to process [StringBuilder] It takes [565000000] nono seconds to process [String] It takes [3000000] nono seconds to process [StringBuffer] It takes [3000000] nono seconds to process [StringBuilder]
從這個結果中能夠看出,測試
不出所料,後兩種比第一種方式要好,15倍到20倍的樣子;優化
後兩種方式比第一種方式要穩定,大概也是真的比較快,尚未到不穩定的階段;ui
StringBuilder比StringBuffer的性能很是接近,稍好一點吧。this
之因此這裏同時測試了StringBuilder和StringBuffer,是由於我記得若是不涉及併發的狀況下,推薦使用StringBuilder;大概是由於StringBuilder沒有同步控制的緣由;code
查看了一下StringBuilder和StringBuffer的源碼,確實也是這樣的:
StringBuilder append的代碼:
@Override public StringBuilder append(String str) { super.append(str); return this; }
StringBuffer append的代碼:
@Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; }
但在一個方法裏面,確定不會存在併發控制的狀況下,java應該有優化能夠去掉這個鎖。(惋惜我不懂要怎麼樣去測試這樣的狀況),因此大部分狀況下,使用StringBuffer也不會成爲問題;