摘要:測試拼接速度測試的結果在循環中,拼接字符串的速度遠低于和利用查看字節碼文件,尋找其中的差異命令行執行結果可以看出,拼接的時候也是通過的方法進行拼接的產生差異的原因是,在每次循環中,拼接的時候都了一個是線程安全的,只比稍慢了一點若不是
String、StringBuilder、StringBuffer 測試拼接速度
@Test public void testString() { long before = System.currentTimeMillis(); String s = ""; for (int i = 0; i < 100000; i++) { s += "a"; } long after = System.currentTimeMillis(); System.out.println("String cost: " + (after - before)); } @Test public void testStringBuilder() { long before = System.currentTimeMillis(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 100000; i++) { sb.append("a"); } long after = System.currentTimeMillis(); System.out.println("StringBuilder cost: " + (after - before)); } @Test public void testStringBuffer() { long before = System.currentTimeMillis(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < 100000; i++) { sb.append("a"); } long after = System.currentTimeMillis(); System.out.println("StringBuffer cost: " + (after - before)); }
測試的結果:
StringBuilder cost: 5 StringBuffer cost: 9 String cost: 14029
在循環中,String 拼接字符串的速度遠低于 StringBuilder 和 StringBuffer
利用 javap 查看字節碼文件,尋找其中的差異
命令行執行
javap -c StringTest.class
結果可以看出,String 拼接的時候也是通過 StringBuilder 的 append 方法進行拼接的
產生差異的原因是,在每次循環中,String 拼接的時候都 new 了一個 StringBuilder
StringBuffer 是線程安全的,只比 StringBuilder 稍慢了一點
public void testString(); Code: 0: ldc #2 // String 2: astore_1 3: iconst_0 4: istore_2 5: iload_2 6: ldc #11 // int 100000 8: if_icmpge 37 11: new #4 // class java/lang/StringBuilder 14: dup 15: invokespecial #5 // Method java/lang/StringBuilder."若不是循環,String 和 StringBuilder 拼接的速度是差不多的":()V 18: aload_1 19: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: ldc #9 // String a 24: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 27: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 30: astore_1 31: iinc 2, 1 34: goto 5 37: return public void testStringBuilder(); Code: 0: new #4 // class java/lang/StringBuilder 3: dup 4: invokespecial #5 // Method java/lang/StringBuilder." ":()V 7: astore_1 8: iconst_0 9: istore_2 10: iload_2 11: ldc #11 // int 100000 13: if_icmpge 29 16: aload_1 17: ldc #9 // String a 19: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: pop 23: iinc 2, 1 26: goto 10 29: return public void testStringBuffer(); Code: 0: new #12 // class java/lang/StringBuffer 3: dup 4: invokespecial #13 // Method java/lang/StringBuffer." ":()V 7: astore_1 8: iconst_0 9: istore_2 10: iload_2 11: ldc #11 // int 100000 13: if_icmpge 29 16: aload_1 17: ldc #9 // String a 19: invokevirtual #14 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer; 22: pop 23: iinc 2, 1 26: goto 10 29: return
java 測試代碼
@Test public void string() { String s = ""; String ss = "cc"; s += "a" + "b" + ss; } @Test public void stringBuilder() { StringBuilder sb = new StringBuilder(); String ss = "cc"; sb.append("a").append("b").append(ss); }
字節碼
public void string(); Code: 0: ldc #2 // String 2: astore_1 3: ldc #3 // String cc 5: astore_2 6: new #4 // class java/lang/StringBuilder 9: dup 10: invokespecial #5 // Method java/lang/StringBuilder."":()V 13: aload_1 14: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 17: ldc #7 // String ab 19: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: aload_2 23: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 26: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 29: astore_1 30: return public void stringBuilder(); Code: 0: new #4 // class java/lang/StringBuilder 3: dup 4: invokespecial #5 // Method java/lang/StringBuilder." ":()V 7: astore_1 8: ldc #3 // String cc 10: astore_2 11: aload_1 12: ldc #9 // String a 14: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 17: ldc #10 // String b 19: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: aload_2 23: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 26: pop 27: return
原因是同樣只 new 了一個 StringBuilder,使用的也是它的 append 方法
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67263.html
摘要:官方說明將一個或多個類文件進行分解。顯示靜態常量為每個類中的方法打印反匯編代碼例如字節碼指令組成。在結果的行直接進行多次的拼接看看最后編譯會是神馬的這句話是對應聲明了一個,然后每次拼接實際使用的是的方法。 Oracle官方說明: javap 將一個或多個類文件進行分解。 使用簡要說明 javap [options] classfile... options 命令行選項,詳細查看后面...
摘要:使用可以方便的對字符串進行拼接。該方法使用進行聲明,說明是一個線程安全的方法。所以,阿里巴巴開發手冊建議循環體內,字符串的連接方式,使用的方法進行擴展。但是,還要強調的是如果不是在循環體中進行字符串拼接的話,直接使用就好了。 摘要: 學習阿里巴巴Java開發手冊。 原文:為什么阿里巴巴不建議在for循環中使用+進行字符串拼接 微信公眾號:Hollis Fundebug經授權轉載,...
摘要:兩個字符串拼接直接調用性能最好。關于的其他最佳實踐用時總是把能確定不為空的變量寫在左邊,如使用判斷空串,避免空指針異常。在需要把其他對象轉換為字符串對象時,使用而不是直接調用方法,因為前者已經對空值進行檢測了,不會拋出空指針異常。 本文來源于問題 Java字符串連接最佳實踐? java連接字符串有多種方式,比如+操作符,StringBuilder.append方法,這些方法各有什么優...
摘要:當然大多數情況下就是我們是在單線程下進行的操作,所以大多數情況下是建議用而不用的,就是速度的原因。 第三階段 JAVA常見對象的學習 StringBuffer和StringBuilder類 (一) StringBuffer類的概述 (1) 基本概述 下文以StringBuffer為例 前面我們用字符串做拼接,比較耗時并且也耗內存(每次都會構造一個新的string對象),而這種拼接操作又...
摘要:不指定容量會顯著降低性能一般使用在方法內部來完成類似功能,因為是線程不安全的,所以用完以后可以丟棄。主要用在全局變量中相同情況下使用相比使用僅能獲得左右的性能提升,但卻要冒多線程不安全的風險。 String 作為最基礎的引用數據類型,日常的開發中被大量的使用。基于不可變的特性,一旦被過度地使用,堆內存就會負荷不堪,甚至影響性能,為此,Java 設計者特意為 String 在方法區中開辟...
閱讀 4716·2021-11-18 13:23
閱讀 903·2021-09-22 15:24
閱讀 1928·2021-09-06 15:00
閱讀 2630·2021-09-03 10:30
閱讀 1287·2021-09-02 15:15
閱讀 2072·2019-08-30 15:54
閱讀 3036·2019-08-30 15:44
閱讀 1457·2019-08-29 15:12