【转载】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的效率:

[java]  view plain  copy
  1. package StringBuilderBufferTest;  
  2.   
  3. public class ToStringPerformanceTest {  
  4.     public static void main(String[] args){  
  5.         long start1=System.nanoTime();  
  6.         StringBuffer strBuffer=new StringBuffer(10000);  
  7.         for(int i=0;i<10000;i++){  
  8.             strBuffer.append("a");  
  9.         }  
  10.         String testStr1=strBuffer.toString();  
  11.         long end1=System.nanoTime();  
  12.         System.out.println("相同字符串StringBuffer拼接并转成string耗时"+(end1-start1)/1000+"微秒");  
  13.           
  14.         long start2=System.nanoTime();  
  15.         StringBuilder strBuilder=new StringBuilder(10000);  
  16.         for(int i=0;i<10000;i++){  
  17.             strBuilder.append("a");  
  18.         }  
  19.         String testStr2=strBuffer.toString();  
  20.         long end2=System.nanoTime();  
  21.         System.out.println("相同字符串StringBuilder拼接并转成string耗时"+(end2-start2)/1000+"微秒");  
  22.           
  23.         StringBuffer buffer=new StringBuffer(testStr1);  
  24.         StringBuilder builder=new StringBuilder(testStr1);  
  25.           
  26.         long start3=System.nanoTime();  
  27.         String s3=buffer.toString();  
  28.         long end3=System.nanoTime();  
  29.         System.out.println("相同字符串单纯StringBuffer.toString()耗时"+(end3-start3)/1000+"微秒");  
  30.           
  31.         long start4=System.nanoTime();  
  32.         String s4=builder.toString();  
  33.         long end4=System.nanoTime();  
  34.         System.out.println("相同字符串单纯StringBuilder.toString()耗时"+(end4-start4)/1000+"微秒");  
  35.     }  
  36. }  

 

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

[java]  view plain  copy
  1. 相同字符串StringBuffer拼接并转成string耗时5142微秒  
  2. 相同字符串StringBuilder拼接并转成string耗时3321微秒  
  3. 相同字符串单纯StringBuffer.toString()耗时13微秒  
  4. 相同字符串单纯StringBuilder.toString()耗时18微秒  

 

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

 

 


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

 


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

 


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

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值