String,StringBuffer,StringBuilder拼接速度的测试

Java面试汇总中老是会有String,StringBuffer,StringBuilder的区别这种面试题,统一的回答是:

三者连接速度由快到慢:StringBuilder,StringBuffer,String

StringBuilder非线程安全,StringBuffer线程安全

String是字符串常量,二StringBuilder和StringBuffer为字符串变量,也就是说String一旦创建就不可更改,每次做连接操作时实际上又重新创建了一个String,然后将拼接后的结果存储在这个新的string对象指向的地址里,由于不断创建新的String对象导致了连接速度大大降低,而StringBuffer和StringBuilder则是直接在字符串变量后进行连接操作,速度才会明显快于String。

至于StringBuffer线程安全则是由于StringBuffer中的大部分方法都被synchronized(关于synchronized关键字本人之前的博客有介绍,感兴趣可以。。。嘿嘿嘿)修饰,简单来说就是实现了同步机制,导致了速度慢于StringBuilder

 那么真实的场景下到底结果如何呢?让我们来梭哈一段代码测试一下

public class StringBuliderBuffer {
	private static StringBuilder sbu=new StringBuilder("a");
	private static StringBuffer sbf=new StringBuffer("a");
	private static String str=new String("a");
	private static long count=1000;
	public static void main(String[] args) {
		
		long startSbuTime=System.currentTimeMillis();
		for (long i = 0; i < count; i++) {
			sbf.append(i);
		}
		long endSbuTime=System.currentTimeMillis();
		System.out.println("StringBuffer运行时间:"+(endSbuTime-startSbuTime));
		
		startSbuTime=System.currentTimeMillis();
		
		for (long i = 0; i < count; i++) {
			sbu.append(i);
		}
		endSbuTime=System.currentTimeMillis();		
		System.out.println("StringBuilder运行时间:"+(endSbuTime-startSbuTime));
		
		startSbuTime=System.currentTimeMillis();
		for (long i = 0; i < count; i++) {
			str=str+i;
		}
		endSbuTime=System.currentTimeMillis();	
		System.out.println("String运行时间:"+(endSbuTime-startSbuTime));
	}
}

分别创建了各自的对象,并且初始化,然后测试执行循环连接,测试连接前后的时间差,结果如下

次数count=1000时

StringBuffer运行时间:1
StringBuilder运行时间:0
String运行时间:3

次数count=100000

StringBuffer运行时间:16
StringBuilder运行时间:0
String运行时间:22418

次数count=1000000

StringBuffer运行时间:78
StringBuilder运行时间:31

次数为1000次时,结果不明显

十万次时结果已经比较明显,StringBuilder的时间仍未0(这个有点诡异),而String时间明显与其它俩天壤之别

一百万次时StringBuilder和StringBuffer差距拉开,总得来说仍在同一个等级上,而String结果仍未完成(此时已等待了10分钟,我洗好了衣服回来仍未结束)

所以应尽少使用String的拼接操作,但是在内存中已经有拼接后的字符串这种情况时,String的速度快于其它两者,可能因为拼接后的字符串如果已经存在,String不会再做拼接操作,而是将当前字符串指向已有字符串的地址,所以速度很快

至于StringBuffer和StringBuilder的选择,由于时间差不多,所以一般选择线程安全的StringBuffer

 

你可能感兴趣的:(java之路,多线程和并发,字符串拼接)