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); } }
简单说明一下测试:
环境,mac os 10.10.4, CPU 2.6 GHz Intel Core i5, Memory 8G;
每个测试跑40000次,计时,并记录结果;
跑三次;
结果是:
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倍的样子;
后两种方式比第一种方式要稳定,大概也是真的比较快,还没有到不稳定的阶段;
StringBuilder比StringBuffer的性能非常接近,稍好一点吧。
之所以这里同时测试了StringBuilder和StringBuffer,是因为我记得如果不涉及并发的情况下,推荐使用StringBuilder;大概是因为StringBuilder没有同步控制的原因;
查看了一下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也不会成为问题;
原文:http://my.oschina.net/u/922297/blog/484857