欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

StringBuider 在什么條件下、如何使用效率更高

 更新時間:2020年06月30日 11:33:08   作者:后青春期的Keats  
都說 StringBuilder 在處理字符串拼接上效率要強于 String,但有時候我們的理解可能會存在一定的偏差。今天小編給大家?guī)硪黄坛剃P于StringBuider 在什么條件下、如何使用效率更高?感興趣的朋友一起看看吧

引言

都說 StringBuilder 在處理字符串拼接上效率要強于 String,但有時候我們的理解可能會存在一定的偏差。最近我在測試數(shù)據(jù)導入效率的時候就發(fā)現(xiàn)我以前對 StringBuilder 的部分理解是錯誤的。 后來我通過實踐測試 + 找原理 的方式搞清楚了這塊的邏輯?,F(xiàn)在將過程分享給大家

測試用例

我們的代碼在循環(huán)中拼接字符串一般有兩種情況

第一種就是每次循環(huán)將對象中的幾個字段拼接成一個新字段,再賦值給對象第二種操作是在循環(huán)外創(chuàng)建一個字符串對象,每次循環(huán)向該字符串拼接新的內容。循環(huán)結束后得到拼接好的字符串

對于這兩種情況,我創(chuàng)建了兩個對照組

第一組:

在每次 For 循環(huán)中拼接字符串,即拼即用、用完即毀。分別使用 String 和 StringBuilder 拼接

 /**
  * 循環(huán)內 String 拼接字符串,一次循環(huán)后銷毀
  */
 public static void useString(){
  for (int i = 0; i < CYCLE_NUM_BIGGER; i++) {
   String str = str1 + i + str2 + i + str3 + i + str4 ;
  }
 }

 /**
  * 循環(huán)內 使用 StringBuilder 拼接字符串,一次循環(huán)后銷毀
  */
 public static void useStringBuilder(){
  for (int i = 0; i < CYCLE_NUM_BIGGER; i++) {
   StringBuilder sb = new StringBuilder();
   String s = sb.append(str1).append(i).append(str2).append(i).append(str3).append(i).append(str4).toString();
  }
 }

第二組:

多次 For 循環(huán)拼接一個字符串,循環(huán)結束后使用字符串,使用后由垃圾回收器回收。也是分別使用 String 和 StringBuilder 拼接

 /**
  * 多次循環(huán)拼接成一個字符串 用 String
  */
 public static void useStringSpliceOneStr (){
  String str = "";
  for (int i = 0; i < CYCLE_NUM_LOWER; i++) {
   str += str1 + str2 + str3 + str4 + i;
  }
 }

 /**
  * 多次循環(huán)拼接成一個字符串 用 StringBuilder
  */
 public static void useStringBuilderSpliceOneStr(){
  StringBuilder sb = new StringBuilder();
  for (int i = 0; i < CYCLE_NUM_LOWER; i++) {
   sb.append(str1).append(str2).append(str3).append(str4).append(i);
  }
 }

為了保證測試質量,在每個測試項目進行前。線程休息 2s,之后空跑 5 次熱身。最后執(zhí)行 5 次求平均時間的方式計算時間

 public static int executeSometime(int kind, int num) throws InterruptedException {
  Thread.sleep(2000);
  int sum = 0;
  for (int i = 0; i < num + 5; i++) {
   long begin = System.currentTimeMillis();

   switch (kind){
    case 1:
     useString();
     break;
    case 2:
     useStringBuilder();
     break;
    case 3:
     useStringSpliceOneStr();
     break;
    case 4:
     useStringBuilderSpliceOneStr();
     break;
    default:
     return 0;
   }

   long end = System.currentTimeMillis();

   if(i > 5){
    sum += (end - begin);
   }
  }
  return sum / num;
 }

主方法

public class StringTest {
 public static final int CYCLE_NUM_BIGGER = 10_000_000;
 public static final int CYCLE_NUM_LOWER = 10_000;
 public static final String str1 = "張三";
 public static final String str2 = "李四";
 public static final String str3 = "王五";
 public static final String str4 = "趙六";


 public static void main(String[] args) throws InterruptedException {
  int time = 0;
  int num = 5;

  time = executeSometime(1, num);
  System.out.println("String拼接 "+ CYCLE_NUM_BIGGER +" 次," + num + "次平均時間:" + time + " ms");

  time = executeSometime(2, num);
  System.out.println("StringBuilder拼接 "+ CYCLE_NUM_BIGGER +" 次," + num + "次平均時間:" + time + " ms");

  time = executeSometime(3, num);
  System.out.println("String拼接單個字符串 "+ CYCLE_NUM_LOWER +" 次," + num + "次平均時間:" + time + " ms");

  time = executeSometime(4, num);
  System.out.println("StringBuilder拼接單個字符串 "+ CYCLE_NUM_LOWER +" 次," + num + "次平均時間:" + time + " ms");

 }
} 

測試結果

測試結果如下

結果分析

第一組

10_000_000 次循環(huán)拼接,在循環(huán)內使用 String 和 StringBuilder 的效率是一樣的!為什么呢?

使用 javap -c StringTest.class 反編譯查看兩個方法編譯后的文件:

可以發(fā)現(xiàn) String 方法拼接字符串編譯器優(yōu)化后使用的就是 StringBuilder、因此用例1 和用例2 的效率是一樣的。

第二組

第二組的結果就是大家喜聞樂見的了,由于 10_000_000 次循環(huán)String 拼接實在太慢所以我采用了 10_000 次拼接來分析。

分析用例3:雖然編譯器會對 String 拼接做優(yōu)化,但是它每次在循環(huán)內創(chuàng)建 StringBuilder 對象,在循環(huán)內銷毀。下次循環(huán)他有創(chuàng)建。相比較用例4在循環(huán)外創(chuàng)建,多了 n 次 new 對象、銷毀對象的操作、n - 1 次將 StringBuilder 轉換成 String 的操作 。效率低也是理所應當了。

擴展

第一組的測試還有一種寫法:

 /**
  * 循環(huán)內 使用 StringBuilder 拼接字符串,一次循環(huán)后銷毀
  */
 public static void useStringBuilderOut(){
  StringBuilder sb = new StringBuilder();
  for (int i = 0; i < CYCLE_NUM_BIGGER; i++) {
//   sb.setLength(0);
   sb.delete(0, sb.length());
   String s = sb.append(str1).append(i).append(str2).append(i).append(str3).append(i).append(str4).toString();
  }
 }

循環(huán)外創(chuàng)建 StringBuilder 每次循環(huán)開始的時候清空 StringBuilder 的內容然后拼接。這種寫法無論使用 sb.setLength(0); 還是 sb.delete(0, sb.length()); 效率都比直接在循環(huán)內使用 String / StringBuilder 慢。奈何才疏學淺我一直想不明白為什么他慢。我猜測是 new 對象的速度比重置長度慢,于是這樣測試了以下:

 public static void createStringBuider() {
  for (int i = 0; i < CYCLE_NUM_BIGGER; i++) {
   StringBuilder sb = new StringBuilder();
  }
 }

 public static void cleanStringBuider() {
  StringBuilder sb = new StringBuilder();
  for (int i = 0; i < CYCLE_NUM_BIGGER; i++) {
   sb.delete(0, sb.length());
  }
 }

但是結果是 cleanStringBuider 更快。讓我摸不著頭腦

如果有大神看到希望可以幫忙分析分析

結論

編譯器會將 String 拼接優(yōu)化成使用 StringBuilder,但是還是有一些缺陷的。主要體現(xiàn)在循環(huán)內使用字符串拼接,編譯器不會創(chuàng)建單個 StringBuilder 以復用

對于多次循環(huán)內拼接一個字符串的需求:StringBuilder 很快,因為其避免了 n 次 new 對象、銷毀對象的操作,n - 1 次將 StringBuilder 轉換成 String 的操作

StringBuilder 拼接不適用于循環(huán)內每次拼接即用的操作方式。因為編譯器優(yōu)化后的 String 拼接也是使用 StringBuilder 兩者的效率一樣。后者寫起來還方便...

到此這篇關于StringBuider 在什么條件下、如何使用效率更高?的文章就介紹到這了,更多相關StringBuider如何使用效率更高內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • VScode敲代碼時自動導入包的解決方案

    VScode敲代碼時自動導入包的解決方案

    這篇文章主要介紹了VScode敲代碼時自動導入包的解決方案,文中通過圖文介紹的非常詳細,對大家學習或者使用vscode具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • git在idea中的沖突解決方法(非常重要)

    git在idea中的沖突解決方法(非常重要)

    這篇文章主要介紹了git在idea中的沖突解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • VSCode設置默認瀏覽器打開的兩種方式

    VSCode設置默認瀏覽器打開的兩種方式

    在使用vscode編輯器的時候,如果我們不設置默認瀏覽器,那么直接打開的是IE瀏覽器,在進行頁面調試的時候無疑是有點麻煩的,這篇文章主要給大家介紹了關于VSCode設置默認瀏覽器打開的兩種方式,需要的朋友可以參考下
    2023-09-09
  • 使用Git進行版本控制的實踐分享

    使用Git進行版本控制的實踐分享

    Git 是目前最流行的分布式版本控制系統(tǒng),廣泛應用于前端開發(fā),Git的強大功能讓開發(fā)者能夠有效管理代碼、協(xié)作開發(fā)、追蹤代碼變更和版本發(fā)布,在本文中,我們將探討前端開發(fā)者在使用 Git 進行版本控制時應遵循的一些最佳實踐,需要的朋友可以參考下
    2024-10-10
  • vscode使用restClient實現(xiàn)各種http請求的操作方法

    vscode使用restClient實現(xiàn)各種http請求的操作方法

    這篇文章主要介紹了vscode使用restClient實現(xiàn)各種http請求的操作方法,定義變量以及使用環(huán)境變量和返回數(shù)據(jù)作為變量的操作代碼,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • Git中smart Checkout與force checkout的區(qū)別及說明

    Git中smart Checkout與force checkout的區(qū)別及說明

    這篇文章主要介紹了Git中smart Checkout與force checkout的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • VScode修改默認生成的HTML模板的方法

    VScode修改默認生成的HTML模板的方法

    這篇文章主要介紹了VScode修改默認生成的HTML模板的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Git下載、安裝與環(huán)境配置的詳細教程

    Git下載、安裝與環(huán)境配置的詳細教程

    這篇文章主要介紹了Git下載、安裝與環(huán)境配置,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • vscode常用插件整理匯總

    vscode常用插件整理匯總

    本文給大家整理匯總了17個常用的vscode裝B插件,都是作者費心整理出來的,希望大家能夠喜歡
    2020-02-02
  • 微信小程序學習之初探小程序

    微信小程序學習之初探小程序

    這兩天“微信小程序”這個詞占據(jù)了朋友圈,大有一番風起云涌之勢,當然,還不可能夸張到使原生App開發(fā)人員失業(yè)這種程度。當然,作為一名技術人員,時刻保持對新技術的好奇心是必須的,所以在網上找大神的教程,搭建了一下開發(fā)環(huán)境,來學習一下這個新的開發(fā)框架。
    2016-09-09

最新評論