最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

引言

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

測試用例

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

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

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

第一組:

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

 /**
  * 循環(huán)內(nèi) 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)內(nèi) 使用 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)結(jié)束后使用字符串,使用后由垃圾回收器回收。也是分別使用 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);
  }
 }

為了保證測試質(zhì)量,在每個測試項目進(jìn)行前。線程休息 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");

 }
} 

測試結(jié)果

測試結(jié)果如下

結(jié)果分析

第一組

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

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

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

第二組

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

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

擴(kuò)展

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

 /**
  * 循環(huán)內(nèi) 使用 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 的內(nèi)容然后拼接。這種寫法無論使用 sb.setLength(0); 還是 sb.delete(0, sb.length()); 效率都比直接在循環(huán)內(nèi)使用 String / StringBuilder 慢。奈何才疏學(xué)淺我一直想不明白為什么他慢。我猜測是 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());
  }
 }

但是結(jié)果是 cleanStringBuider 更快。讓我摸不著頭腦

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

結(jié)論

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

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

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

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

相關(guān)文章

  • 微信 小程序開發(fā)環(huán)境搭建詳細(xì)介紹

    微信 小程序開發(fā)環(huán)境搭建詳細(xì)介紹

    這篇文章主要介紹了微信 小程序開發(fā)環(huán)境搭建詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • windows下Idea使用git clone failed. Could not read from remote repository.

    windows下Idea使用git clone failed. Could not read from remote r

    這篇文章主要介紹了windows下Idea使用git clone failed. Could not read from remote repository.,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • 不同系統(tǒng)打開JSON文件的6種方法(總有一種適合你)

    不同系統(tǒng)打開JSON文件的6種方法(總有一種適合你)

    JSON文件本質(zhì)上是一個文本文件,可以使用任何文本編輯器打開,本文推薦使用專門的代碼編輯器,這篇文章主要給大家介紹了關(guān)于不同系統(tǒng)打開JSON文件的6種方法,需要的朋友可以參考下
    2024-02-02
  • 高性能WEB開發(fā) web性能測試工具推薦

    高性能WEB開發(fā) web性能測試工具推薦

    WEB性能測試工具主要分為三種,一種是測試頁面資源加載速度的,一種是測試頁面加載完畢后頁面呈現(xiàn)、JS操作速度的,還有一種是總體上對頁面進(jìn)行評價分析,下面分別對這些工具進(jìn)行介紹,如果誰有更好的工具也請一起分享下。
    2010-05-05
  • 在MAUI中使用Masa?Blazor的方法

    在MAUI中使用Masa?Blazor的方法

    這篇文章主要介紹了在MAUI中使用Masa?Blazor,探索一下如何在MAUI中使用Masa?Blazor,開頭介紹了什么是MAUI,需要的朋友可以參考下
    2022-04-04
  • OpenAI?函數(shù)調(diào)用示例及功能入門教程

    OpenAI?函數(shù)調(diào)用示例及功能入門教程

    這篇文章主要為大家介紹了OpenAI?函數(shù)調(diào)用示例及功能入門教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • 文本文件編碼方式區(qū)別

    文本文件編碼方式區(qū)別

    當(dāng)一個軟件打開一個文本時,它要做的第一件事是決定這個文本究竟是使用哪種字符集的哪種編碼保存的。
    2008-09-09
  • Idea 2019.3 本應(yīng)該搜索到的插件卻搜索不到的解決方法

    Idea 2019.3 本應(yīng)該搜索到的插件卻搜索不到的解決方法

    這篇文章主要介紹了Idea 2019.3 本應(yīng)該搜索到的插件卻搜索不到,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • git設(shè)置用戶名密碼的示例代碼

    git設(shè)置用戶名密碼的示例代碼

    這篇文章主要介紹了git設(shè)置用戶名密碼的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 前端開發(fā)工具nvim替帶VSCode的安裝配置

    前端開發(fā)工具nvim替帶VSCode的安裝配置

    這篇文章主要為大家介紹了一款前端開發(fā)工具nvim代替VSCode的配置使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07

最新評論

襄城县| 启东市| 晋江市| 兰西县| 揭西县| 仙桃市| 兰考县| 桐柏县| 政和县| 乐清市| 新密市| 马鞍山市| 思南县| 城口县| 南宁市| 鹤壁市| 常山县| 收藏| 文安县| 文化| 镇安县| 筠连县| 兴宁市| 乌兰浩特市| 和静县| 耒阳市| 正镶白旗| 新营市| 富民县| 什邡市| 上林县| 灌云县| 仁怀市| 东阳市| 温宿县| 资阳市| 和林格尔县| 饶阳县| 台江县| 吉木乃县| 登封市|