JAVA的字串拼接與效能

來源:互聯網
上載者:User

概述:本文主要研究的是JAVA的字串拼接的效能,原文中的測試代碼在功能上並不等價,導致concat的測試意義不大。不過原作者在評論欄給了新的concat結果,如果有興趣的同學建議自己修改代碼測試。

原文出處:http://www.venishjoe.net/2009/11/java-string-concatenation-and.html

在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庫進行封裝。首先我們先定義迭代次數

private static final int OUTER_ITERATION=20;private static final int INNER_ITERATION=50000;

接下來,我們將使用上述4個方法來實現我們的測試代碼。

String addTestStr = "";String concatTestStr = "";StringBuffer concatTestSb = null;StringBuilder concatTestSbu = null;for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {    StopWatch stopWatch = new LoggingStopWatch("StringAddConcat");    addTestStr = "";    for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++) addTestStr += "*";    stopWatch.stop();}        for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {    StopWatch stopWatch = new LoggingStopWatch("StringConcat");    concatTestStr = "";    for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++) concatTestStr = concatTestStr.concat("*");    stopWatch.stop();}for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {    StopWatch stopWatch = new LoggingStopWatch("StringBufferConcat");    concatTestSb = new StringBuffer();    for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++) concatTestSb.append("*");    stopWatch.stop();}for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {    StopWatch stopWatch = new LoggingStopWatch("StringBuilderConcat");    concatTestSbu = new StringBuilder();    for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++) concatTestSbu.append("*");    stopWatch.stop();}

接下來通過運行程式來產生效能指標。我的運行環境是64位的Windown7作業系統,32位的JVM(7-ea) 帶4GB記憶體,雙核Quad 2.00GHz的CPU的機器.

經過20次迭代後,我們得到如下的資料:

結果非常完美如我們想象的那樣。唯一比較有趣的事情是為什麼String.concat也很不錯,我們都知道,String是一個常類(初始化後就不會改變的類),那麼為什麼concat的效能會更好一些呢。(譯者注:其實原文作者的測試代碼有問題,對於concat()方法的測試代碼應該寫成concatTestStr=concatTestStr.concat(“*”)才對。)為了回答這個問題,我們應該看看concat反編譯出來的位元組碼。在本文的下載包裡麵包含了所有的位元組碼,但是現在我們先看一下concat的這個程式碼片段:

45: new #7; //class java/lang/StringBuilder48: dup49: invokespecial #8; //Method java/lang/StringBuilder."":()V52: aload_153: invokevirtual #9; //Method java/lang/StringBuilder.append:    (Ljava/lang/String;)Ljava/lang/StringBuilder;56: ldc #10; //String *58: invokevirtual #9; //Method java/lang/StringBuilder.append:    (Ljava/lang/String;)Ljava/lang/StringBuilder;61: invokevirtual #11; //Method java/lang/StringBuilder.toString:()    Ljava/lang/String;64: astore_1

這段代碼是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.

文章來源:http://coolshell.cn/?p=2235

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.