StringBuilder性能真的优于StringBuffer?!!!!

大家都知道,StringBuilder和StringBuffer主要区别是前者不是线程安全的,后者是线程安全的,余JDK预留的对外接口几乎是一模一样的,所以在确定线程安全的环境的前提下,优先使用SringBuilder,肯定不相同条件下的StringBuffer性能要高,因为那维护同步数据的正确性肯定要消耗资源的。

然而在今天的事业部代码质量报告会上,我在讲解StringBuilder和StirngBuffer的区别以及为什么优于“+”拼接字符串时候,一位经验丰富的前辈指点了一下说StringBuilder尽管在拼接字符串时效率高于StringBuffer,但是最终还是好转成String类型的,而在大字符串拼接的情况下StringBuffer的toString()要比StringBuilder的toString()执行速度将近快3.5倍,所以线程安全的情况下还是用StringBuffer,当时听了很是高心,因为自己不知道这个地方,又涨姿势了。
晚上自己想一探究竟,看了2个类的重写toString()方法的源码除了加了同步锁之外,都是return New String(value,offset,count),纳了闷了,都是底层都是调用的同一个方法,反而怎么是同步的StringBuffer效率高呢,不行,自己写了一个测试程序,来单独验证一下2个toString的效率

package StringBuilderBufferTest;

public class ToStringPerformanceTest {
	public static void main(String[] args){
		long start1=System.nanoTime();
		StringBuffer strBuffer=new StringBuffer(10000);
		for(int i=0;i<10000;i++){
			strBuffer.append("a");
		}
		String testStr1=strBuffer.toString();
		long end1=System.nanoTime();
		System.out.println("相同字符串StringBuffer拼接并转成string耗时"+(end1-start1)/1000+"微秒");
		
		long start2=System.nanoTime();
		StringBuilder strBuilder=new StringBuilder(10000);
		for(int i=0;i<10000;i++){
			strBuilder.append("a");
		}
		String testStr2=strBuffer.toString();
		long end2=System.nanoTime();
		System.out.println("相同字符串StringBuilder拼接并转成string耗时"+(end2-start2)/1000+"微秒");
		
		StringBuffer buffer=new StringBuffer(testStr1);
		StringBuilder builder=new StringBuilder(testStr1);
		
		long start3=System.nanoTime();
		String s3=buffer.toString();
		long end3=System.nanoTime();
		System.out.println("相同字符串单纯StringBuffer.toString()耗时"+(end3-start3)/1000+"微秒");
		
		long start4=System.nanoTime();
		String s4=builder.toString();
		long end4=System.nanoTime();
		System.out.println("相同字符串单纯StringBuilder.toString()耗时"+(end4-start4)/1000+"微秒");
	}
}

运行了数十次,平均结果接近下边结果:

相同字符串StringBuffer拼接并转成string耗时5142微秒
相同字符串StringBuilder拼接并转成string耗时3321微秒
相同字符串单纯StringBuffer.toString()耗时13微秒
相同字符串单纯StringBuilder.toString()耗时18微秒

让我大跌眼镜,果然是StringBuffer的toString方法效率略高一些,但不是2个类的性能瓶颈,2个类的主要性能差别还是差在同步与非同步上。
后来和前辈请教了一下,又让我吃惊的是,前辈用JUnit测试的和我大相反,如下:

StringBuilder性能真的优于StringBuffer?!!!!_第1张图片


纳了闷了,怎么会这样,后台我让前辈加上初始容量40000,结果还是与我的大相反:

StringBuilder性能真的优于StringBuffer?!!!!_第2张图片


不行,这是怎么回事,得会前辈又给了我个截图,如下:

StringBuilder性能真的优于StringBuffer?!!!!_第3张图片


前辈如果连续调用测试程序,我的原始测试程序才比较接近点前辈的。
倒腾了半天,又对这2个类有了重新的认识,StringBuffer的toSting方法稍好一些StringBuilder的,至于为什么,我也弄不明白这里边的道理。而非要比较StringBuffer和StringBuilder在线程安全的情况下相同的外界条件下到底哪个性能高哪个性能低,这个真不能一口咬死一口认定就是谁谁高,真要根据当时的项目进行测试,才能得出哪个性能高哪个性能低,进而抉择选择哪个工具更合适。
其实,项目中,如果字符串不是非常的大并发量不是非常的高,StringBuffer或者StringBuilder并不是项目中的性能瓶颈,真没必要太纠结与选择哪个的问题,在此前提下,为了一个很好的编码规范,建议大家确定线程安全的情况下选择StingBuilder,线程不安全的情况下还是用StringBuffer,毕竟很多书中也都是这么建议的。

转载请注明—作者:Java我人生(陈磊兴)原文出处:http://blog.csdn.net/chenleixing/article/details/44087241

你可能感兴趣的:(StringBuilder性能真的优于StringBuffer?!!!!)