<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                # 七行代碼的九種性能優化方法 原題如下,如下代碼用于拼接字符串,試找出所有9種性能優化方法 ```java public String buildProvince(List<Org> orgs){ StringBuilder sb = new StringBuilder(); for(Org org:orgs){ if(sb.length()!=0){ sb.append(",") } sb.append(org.getProvinceId()); } return sb.toString(); } ``` > 所有優化方法實現在 https://gitee.com/xiandafu/java-performance/tree/master/helloworld,優化的JMH測試結果也在例子的comment里 > > 這個例子的9種優化方法,在本書里均有介紹 ## 1 檢查是否為空 提前檢測參數,盡早返回可能的結果. ```java public static String buildProvinceWithEmptyCheck(List<Org> orgs){ //檢測是否為空 if(orgs.isEmpty()){ return ""; } ....... } ``` ## 2 檢測集合只有一個 如果集合只有一個,則只需要做特殊處理 ```java public static String buildProvinceWithSizeCheck(List<Org> orgs){ //如果只包含一個元素 if(orgs.size()==1){ return String.valueOf(orgs.get(0).getProvinceId()); } ....... } ``` Java的String的split方法,就是對正則表達式判斷,如果長度為1,則不采用正則表達式解析字符串,從而提供系統性能 ## 3 采用subString ```java public static String buildProvinceWithSubString(List<Org> orgs){ StringBuilder sb = new StringBuilder(); for(Org org:orgs){ sb.append(org.getProvinceId()).append(","); } //去掉最后一個逗號 return sb.substring(0,sb.length()); } ``` 這樣,避免了每次循環中的使用if來判斷。(注意,這里假定orgs是有值的) ## 4 使用char拼接 ```java public static String buildProvinceWithChar(List<Org> orgs){ StringBuilder sb = new StringBuilder(); for(Org org:orgs){ //使用char 代替String sb.append(org.getProvinceId()).append(','); } sb.setLength(sb.length()-1); return sb.toString(); } ``` 通過StringBuilder源碼,可以看到append(char)效率比append(String)要高多了 ## 5 預先估計StringBuilder容量 對集合,StringBuilder等預先估計一個容量,避免容量再次增長帶來的性能影響 ```java public static String buildProvinceWithInitCapacity(List<Org> orgs){ //假設省Id不超過2位,初始化一個大小 StringBuilder sb = new StringBuilder(orgs.size()*3); ....... } ``` ## 6 采用StringBuffer StringBuffer并不比StringBuilder慢 ```java public static String buildProvinceWithStringBuffer(List<Org> orgs){ //StringBuffer StringBuffer sb = new StringBuffer(); ........ return sb.toString(); } ``` 一方面虛擬機有鎖逃逸優化,避免了Synchronized 帶來的性能影響,另外,StringBuffer的toString方法實現比較特別,它的實現如下 ```java @Override public synchronized String toString() { return new String(toStringCache, true); } ``` 也就是用StringBuffer構造String的時候,復用了StringBuffer的char[], 對比StringBuilder,則采用更安全的方式,構造String的時候重新復制了一份。 ## 7 provinceId提前轉為字符串 int轉為字符串實際上相當耗時,可以提前轉化,這也是所有優化方式里最明顯的的一種 ```java public static String buildProvinceWithCacheData(List<Org> orgs){ StringBuilder sb = new StringBuilder(); for(Org org:orgs){ //使用預先初始化好的chars char[] chars = strProvince[org.getProvinceId()]; sb.append(chars).append(','); } sb.setLength(sb.length()-1); return sb.toString(); } static char[][] strProvince; static{ strProvince = new char[31][]; for(int i=0;i<31;i++){ strProvince[i] = String.valueOf(i).toCharArray(); } } ``` 再Java源碼里,int裝箱成Integer,也采用預先初始化了一部分Integer數據,以提高性能 ## 8 緩存StringBuilder 如果每次調用都需要構建一個StringBuilder,可以放到ThreadLocal里緩存起來,也有較好的性能 ```java public static String buildProvinceWithCache(List<Org> orgs){ StringBuilder sb = local.get(); for(Org org:orgs){ if(sb.length()!=0){ sb.append(","); } sb.append(org.getProvinceId()); } String str = sb.toString(); sb.setLength(0); return str; } static ThreadLocal<StringBuilder> local = ThreadLocal.withInitial((Supplier) () -> new StringBuilder()); ``` 在Java源碼里,FloatingDecimal,用于講Double轉化String,也是采用了類似機制。 Jackson,FastJSON等高速序列化工具,也會提供可復用的輸出緩存區。如Jackson使用了BufferRecycler ## 9 循環展開 其他語言都有循環展開作為性能優化,Java也有此效果,這里僅僅作為演示例子,在此場景不具備實際用途 ```java /** * 如果預先知道容量,比如能整除4,可以減少循環判斷 * @param orgs * @return */ public static String buildProvinceWithLoop(List<Org> orgs){ StringBuilder sb = new StringBuilder(); int count = orgs.size()/4; int i=0; for(;i<count;i++){ sb.append(orgs.get(i).getProvinceId()).append(","); sb.append(orgs.get(i+1).getProvinceId()).append(","); sb.append(orgs.get(i+2).getProvinceId()).append(","); sb.append(orgs.get(i+3).getProvinceId()).append(","); } //去掉最后一個逗號 sb.setLength(sb.length()-1); return sb.toString(); } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看