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測試的和我大相反,如下:

 

 


納了悶了,怎麼會這樣,後臺我讓前輩加上初始容量40000,結果還是與我的大相反:

 


不行,這是怎麼回事,得會前輩又給了我個截圖,如下:

 


       前輩如果連續調用測試程序,我的原始測試程序才比較接近點前輩的。
       倒騰了半天,又對這2個類有了重新的認識,StringBuffer的toSting方法稍好一些StringBuilder的,至於爲什麼,我也弄不明白這裏邊的道理。而非要比較StringBuffer和StringBuilder在線程安全的情況下相同的外界條件下到底哪個性能高哪個性能低,這個真不能一口咬死一口認定就是誰誰高,真要根據當時的項目進行測試,才能得出哪個性能高哪個性能低,進而抉擇選擇哪個工具更合適。
       其實,項目中,如果字符串不是非常的大併發量不是非常的高,StringBuffer或者StringBuilder並不是項目中的性能瓶頸,真沒必要太糾結與選擇哪個的問題,在此前提下,爲了一個很好的編碼規範,建議大家確定線程安全的情況下選擇StingBuilder,線程不安全的情況下還是用StringBuffer,畢竟很多書中也都是這麼建議的。

轉載請註明—作者:Java我人生(陳磊興)   原文出處:http://blog.csdn.net/chenleixing/article/details/44087241

發佈了133 篇原創文章 · 獲贊 336 · 訪問量 364萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章