1. 程式人生 > >Java 5種字串拼接方式效能比較

Java 5種字串拼接方式效能比較

總結:字串優化

由於String物件時不可變物件,因此在需要對字串進行修改操作時(如字串連線和替換),String物件總是會生成新的物件,所以其效能相對較差。

String常量的累加操作:對於靜態字串的連線操作,Java在編譯時會進行徹底的優化,將多個連線操作的字串在編譯時合成一個單獨的長字串。

String變數的累加操作:底層使用了StringBuilder的功能。
StringBuffer和StringBuilder的擴容策略:當字串緩衝區容量不足時,原有容量將會加倍,以新的容量來申請記憶體空間,建立新的char陣列,然後將原陣列中的內容複製到這個新的陣列當中。因此,對於大物件的擴容會涉及大量的記憶體複製操作。所以,如果能夠預先評估StringBuilder或StringBuffer的大小,將能夠有效的節省這些操作,從而提高系統的效能。

JAVA的字串拼接與效能

在JAVA中拼接兩個字串的最簡便的方式就是使用操作符”+”了。如果你用”+”來連線固定長度的字串,可能效能上會稍受影響,但是如果你是在迴圈中來”+”多個串的話,效能將指數倍的下降。假設有一個字串,我們將對這個字串做大量迴圈拼接操作,使用”+”的話將得到最低的效能。但是究竟這個效能有多差?

如果我們同時也把StringBuffer,StringBuilder或String.concat()放入效能測試中,結果又會如何呢?本文將會就這些問題給出一個答案!

  我們將使用Per4j來計算效能,因為這個工具可以給我們一個完整的效能指標集合,比如最小,最大耗時,統計時間段的標準偏差等。在測試程式碼中,為了得到一個準確的標準偏差值,我們將執行20個拼接”*”50,000次的測試。下面是我們將使用到的拼接字串的方法:

  Concatenation Operator (+)

  String concat method – concat(String str)

  StringBuffer append method – append(String str)

  StringBuilder append method – append(String str)

  最後,我們將看看位元組碼,來研究這些方法到底是如何執行的。現在,讓我們先開始來建立我捫的類。注意為了計算每個迴圈的效能,程式碼中的每段測試程式碼都需要用Per4J庫進行封裝。首先我們先定義迭代次數
  1 private static final int OUTER_ITERATION=20;
  2 private static final int INNER_ITERATION=50000;

  接下來,我們將使用上述4個方法來實現我們的測試程式碼。
  01 String addTestStr = "";
  02 String concatTestStr = "";
  03 StringBuffer concatTestSb = null;
  04 StringBuilder concatTestSbu = null;
  05 for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
  06 StopWatch stopWatch = new LoggingStopWatch("StringAddConcat");
  07 addTestStr = "";
  08 for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
  09 addTestStr += "*";
  10 stopWatch.stop();
  11 }
  12 for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
  13 StopWatch stopWatch = new LoggingStopWatch("StringConcat");
  14 concatTestStr = "";
  15 for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
  16 concatTestStr.concat("*");
  17 stopWatch.stop();
  18 }
  19 for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
  20 StopWatch stopWatch = new LoggingStopWatch("StringBufferConcat");
  21 concatTestSb = new StringBuffer();
  22 for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
  23 concatTestSb.append("*");
  24 stopWatch.stop();
  25 }
  26 for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
  27 StopWatch stopWatch = new LoggingStopWatch("StringBuilderConcat");
  28 concatTestSbu = new StringBuilder();
  29 for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
  30 concatTestSbu.append("*");
  31 stopWatch.stop();
  32 }
  接下來通過執行程式來生成效能指標。我的執行環境是64位的Windown7作業系統,32位的JVM(7-ea) 帶4GB記憶體,雙核Quad 2.00GHz的CPU的機器.
  經過20次迭代後,我們得到如下的資料:

Java <wbr>5種字串拼接方式效能比較


  結果非常完美如我們想象的那樣。唯一比較有趣的事情是為什麼String.concat也很不錯,我們都知道,String是一個常類(初始化後就不會改變的類),那麼為什麼concat的效能會更好一些呢。(譯者注:其實原文作者的測試程式碼有問題,對於concat()方法的測試程式碼應該寫成concatTestStr=concatTestStr.concat(“*”)才對。)為了回答這個問題,我們應該看看concat反編譯出來的位元組碼。在本文的下載包裡面包含了所有的位元組碼,但是現在我們先看一下concat的這個程式碼片段:
  01 46: new #6; //class java/lang/StringBuilder
  02 49: dup
  03 50: invokespecial #7; //Method java/lang/StringBuilder."":()V
  04 53: aload_1
  05 54: invokevirtual #8; //Method java/lang/StringBuilder.append:
  06 (Ljava/lang/String;)Ljava/lang/StringBuilder;
  07 57: ldc #9; //String *
  08 59: invokevirtual #8; //Method java/lang/StringBuilder.append:
  09 (Ljava/lang/String;)Ljava/lang/StringBuilder;
  10 62: invokevirtual #10; //Method java/lang/StringBuilder.toString:()
  11 Ljava/lang/String;
  12 65: astore_1
  13 66: iinc 7, 1
  14 69: goto 38

  這段程式碼是String.concat()的位元組碼,從這段程式碼中,我們可以清楚的看到,concat()方法使用了StringBuilder,concat()的效能應該和StringBuilder的一樣好,但是由於額外的建立StringBuilder和做.append(str).append(str).toString()的操作,使得concate的效能會受到一些影響,所以StringBuilder和String Cancate的時間是1.8和3.3。

  因此,即時在做最簡單的拼接時,如果我們不想建立StringBuffer或StringBuilder例項使,我們也因該使用concat。但是對於大量的字串拼接操作,我們就不應該使用concat(譯者注:因為測試程式碼功能上並不完全等價,更換後的測試程式碼concat的平均處理時間是1650.9毫秒。這個結果在原文的評論裡面。),因為concat會降低你程式的效能,消耗你的cpu。因此,在不考慮執行緒安全和同步的情況下,為了獲得最高的效能,我們應儘量使用StringBuilder

相關推薦

Java 5字串拼接方式效能比較

最近寫一個東東,可能會考慮到字串拼接,想了幾種方法,但對效能未知,於是用Junit寫了個單元測試。 程式碼如下: import java.util.ArrayList; import java.util.List; import org.apache.commons.la

Java 5字串拼接方式效能比較

總結:字串優化 由於String物件時不可變物件,因此在需要對字串進行修改操作時(如字串連線和替換),String物件總是會生成新的物件,所以其效能相對較差。 String常量的累加操作:對於靜態字串的連線操作,Java在編譯時會進行徹底的優化,將多個連線操作的字串

java字串拼接方式效能分析

前幾天寫一個防重複提交的元件的時候,有一個操作是需要將各個欄位的字串拼接成一個requestKey。看了別人的程式碼,我發現,中介軟體這種東西,每天都要處理幾百幾千萬的請求,但是裡面很多字串拼接的時候還是很原始的“+”號拼接,如果將所有的字串拼接操作都換成更高效

C#三字串拼接方法效能淺析

2)String.Format的原始碼: public static String Format(IFormatProvider provider, String format, params Object[] args) {    if (format == null || args == null)  

java java中subString、split、stringTokenizer三擷取字串方法的效能比較

面試的時候,string  基本上是必須問的知識   突然想起面試的時候曾經被人問過:都知道在大資料量情況下,使用String的split擷取字串效率很低,有想過用其他的方法替代嗎?用什麼替代?我當時的回答很斬釘截鐵:沒有。 google了一下,發現有2中替代方法,於

Java 4陣列複製方式效能比較

package com.demo.main; import java.util.Arrays; /** * <ol>複製陣列的4種方法 * <li>for</li> * <li>clone</li&

Java中substring、split、StringTokenizer三擷取字串方法的效能比較

最近在閱讀java.lang下的原始碼,讀到String時,突然想起面試的時候曾經被人問過:都知道在大資料量情況下,使用String的split擷取字串效率很低,有想過用其他的方法替代嗎?用什麼替代?我當時的回答很斬釘截鐵:沒有。 Google了一下,發現有2種替代方法,於是

Java筆記】IO流中四檔案複製方式效率比較

位元組流檔案複製方式: (1)位元組流讀寫單個位元組 (2)位元組流讀寫位元組陣列 (3)位元組緩衝流讀寫單個位元組 (4)位元組緩衝流讀寫位元組陣列 import java.io.BufferedInputStream; import java.io.BufferedOutpu

java指定編碼的按行讀寫txt檔案(幾讀寫方式比較

輸入輸出的幾種形式 1.FileReader,FileWriter File r = new File("temp.txt") FileReader f = new FileReader(name);//讀取檔案name BufferedReader b = new Buf

JAVA中四操作xml方式比較

. 介紹 1)DOM(JAXP Crimson解析器) DOM是用與平臺和語 言無關的方式表示XML文件的官方W3C標準。DOM是以層次結構組織的節點或資訊片斷的集合。這個層次結構允許開發人員在樹中尋找 特定資訊。分析該結構通常需要載入整個文件和構造層次結構,然後才能做任何工作。由於它是基於資訊層次

java string字串拼接為什麼效能低,迴圈慢

字串迴圈+效能    @Test    public void test() { ​        long s1 = System.currentTimeMillis();        String str = "";        for (int i =

Nginx upstream的5權重分配方式分享

weight 一個 當前 共享 結果 壓力 宕機 clas 機器 Nginx負載均衡的分發方式有4種: 1.輪詢,默認采取此方式,Nginx會按照請求時間的先後順序進行輪詢分發,若某臺Web Server宕機,Nginx自動將其摘掉。 2.

map的5遍歷方式

entry keyset clas emp com spa post pmap next() Map<String, Integer> tempMap = new HashMap<String, Integer>(); tempMap.pu

Java 之 檔案讀寫及效能比較總結

Java 之 檔案讀寫及效能比較總結 2014年05月12日 17:56:49 閱讀數:21765  幹Java這麼久,一直在做WEB相關的專案,一些基礎類差不多都已經忘記。經常想得撿起,但總是因為一些原因,不能如願。 其實不是沒有時間,只是有些時候疲於總結,今得空,下定決心

二分法拼接字串——字串拼接節約效能

字串拼接通常用迴圈,這樣如果迴圈次數過大,就會影響效能,使用一種方法可以優化效能 方法一:(傳統方法)     function repeat(char,n){       var str = ""; &nb

java中String字串拼接“+”和StringBuffer的效率對比

1、前言 (1)最近在做資料傳輸時,由於接收的資料量較大,在字串拼接時使用了以前感覺方便的“+”進行字串拼接,最後拼接到最後時間越來越多,導致效率變慢。 2、String拼接 首先來看一下兩個String用“+”號拼接需要的時間 String aa="E0 00 00 00 00

linux下Nginx反向代理多個tomcat(單獨訪問或叢集配置) Nginx upstream的5權重分配方式

第一步需要在你的伺服器上安裝Nginx,請檢視此文章:https://blog.csdn.net/u013641234/article/details/73838472 安裝完成以後,啟動Nginx,看看是否能夠正常訪問, 然後開始配置Nginx反向代理 : 同一臺伺服器或多臺伺服

WebSocket 框架的效能比較

前一篇文章使用四種框架分別實現百萬websocket常連線的伺服器介紹了四種websocket框架的測試方法和基本資料。 最近我又使用幾個框架實現了websocket push伺服器的原型,並專門對這七種實現做了測試。 本文記錄了測試結果和一些對結果的分析。 這七種框架是: Netty

字串輸出方式

第一種 #include<stdio.h> int main(int argc, const char *argv[]) { char fruit[][20] = {"Apple","Oranger","Banana","watermelen","strawmerry"};

Windows系統下Oracle配置服務的5Host書寫方式

通過Oracle 工具 Net Manager 可以建立Oracle服務用來連線各項資料庫例項。 這種服務配置最終修改的是tnsnames.ora 檔案,這個檔案路徑一般位於 %ORACLE_HOME%/NETWORK\ADMIN 目錄下,%ORACLE_HOME% 為安裝的Oracl