<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    love fish大鵬一曰同風起,扶搖直上九萬里

    常用鏈接

    統計

    積分與排名

    friends

    link

    最新評論

    String,StringBuffer,StringBuilder(轉載)

           簡要的說, String 類型和 StringBuffer 類型的主要性能區別其實在于 String 是不可變的對象(為什么?問問 Java 的設計者吧,為什么 String 不是原生類型呢?)因此在每次對 String 類型進行改變的時候其實都等同于生成了一個新的 String 對象,然后將指針指向新的 String 對象,所以經常改變內容的字符串最好不要用 String ,因為每次生成對象都會對系統性能產生影響,特別當內存中無引用對象多了以后, JVM GC 就會開始工作,那速度是一定會相當慢的。這里嘗試舉個不是很恰當的例子:

           String S1 = “abc”;

           For(int I = 0 ; I < 10000 ; I ++)  // For 模擬程序的多次調用

           {

                  S1 + = “def”;

                  S1 = “abc”;

    }

    如果是這樣的話,到這個 for 循環完畢后,如果內存中的對象沒有被 GC 清理掉的話,內存中一共有 萬個了,驚人的數目,而如果這是一個很多人使用的系統,這樣的數目就不算很多了,所以大家使用的時候一定要小心。

    而如果是使用 StringBuffer 類則結果就不一樣了,每次結果都會對 StringBuffer 對象本身進行操作,而不是生成新的對象,再改變對象引用。所以在一般情況下我們推薦使用 StringBuffer ,特別是字符串對象經常改變的情況下。而在某些特別情況下, String 對象的字符串拼接其實是被 JVM 解釋成了 StringBuffer 對象的拼接,所以這些時候 String 對象的速度并不會比 StringBuffer 對象慢,而特別是以下的字符串對象生成中, String 效率是遠要比 StringBuffer 快的:

           String S1 = “This is only a” + “ simple” + “ test”;

           StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

           你會很驚訝的發現,生成 String S1 對象的速度簡直太快了,而這個時候 StringBuffer 居然速度上根本一點都不占優勢。其實這是 JVM 的一個把戲,在 JVM 眼里,這個

           String S1 = “This is only a” + “ simple” + “test”; 其實就是:

           String S1 = “This is only a simple test”; 所以當然不需要太多的時間了。但大家這里要注意的是,如果你的字符串是來自另外的 String 對象的話,速度就沒那么快了,譬如:

    String S2 = “This is only a”;

    String S3 = “ simple”;

    String S4 = “ test”;

    String S1 = S2 +S3 + S4;

    這時候 JVM 會規規矩矩的按照原來的方式去做, S1 對象的生成速度就不像剛才那么快了,一會兒我們可以來個測試作個驗證。

    由此我們得到第一步結論:

    在大部分情況下 StringBuffer > String

           StringBuilder 跟他們比又怎么樣呢?先簡單介紹一下, StringBuilder JDK5.0 中新增加的一個類,它跟 StringBuffer 的區別看下面的介紹(來源 JavaWorld ):

           Java.lang.StringBuffer 線程安全的可變字符序列。類似于 String 的字符串緩沖區,但不能修改。可將字符串緩沖區安全地用于多個線程。可以在必要時對這些方法進行同步,因此任意特定實例上的所有操作就好像是以串行順序發生的,該順序與所涉及的每個線程進行的方法調用順序一致。

           每個字符串緩沖區都有一定的容量。只要字符串緩沖區所包含的字符序列的長度沒有超出此容量,就無需分配新的內部緩沖區數組。如果內部緩沖區溢出,則此容量自動增大。從 JDK 5.0 開始,為該類增添了一個單個線程使用的等價類,即 StringBuilder 。與該類相比,通常應該優先使用 StringBuilder 類,因為它支持所有相同的操作,但由于它不執行同步,所以速度更快。

    但是如果將 StringBuilder 的實例用于多個線程是不安全的。需要這樣的同步,則建議使用 StringBuffer

    這樣說估計大家都能明白他們之間的區別了,那么下面我們再做一個一般性推導:

    在大部分情況下 StringBuilder > StringBuffer

    因此,根據這個不等式的傳遞定理: 在大部分情況下

    StringBuilder > StringBuffer > String

    既然有這樣的推導結果了,我們做個測試驗證一下:

    測試代碼如下:

    public class testssb {

       

        /** Creates a new instance of testssb */

        final static int ttime = 10000;// 測試循環次數

        public testssb() {

        }

       

        public void test(String s){

            long begin = System.currentTimeMillis();

            for(int i=0;i<ttime;i++){

                s += "add";

            }

            long over = System.currentTimeMillis();

            System.out.println(" 操作 "+s.getClass().getName()+" 類型使用的時間為: "

                + (over - begin) + " 毫秒 " );       

        }

        public void test(StringBuffer s){

            long begin = System.currentTimeMillis();

            for(int i=0;i<ttime;i++){

                s.append("add");

            }

            long over = System.currentTimeMillis();

            System.out.println(" 操作 "+s.getClass().getName()+" 類型使用的時間為: "

                + (over - begin) + " 毫秒 " );       

        }

        public void test(StringBuilder s){

            long begin = System.currentTimeMillis();

            for(int i=0;i<ttime;i++){

                s.append("add");

            }

            long over = System.currentTimeMillis();

            System.out.println(" 操作 "+s.getClass().getName()+" 類型使用的時間為: "

                + (over - begin) + " 毫秒 " );       

        }

        // String 直接進行字符串拼接的測試

        public void test2(){

            String s2 = "abadf";

            long begin = System.currentTimeMillis();

            for(int i=0;i<ttime;i++){

                String s = s2 + s2 + s2 ;

            }

            long over = System.currentTimeMillis();

            System.out.println(" 操作字符串對象引用相加類型使用的時間為: "

                + (over - begin) + " 毫秒 " );       

        }

        public void test3(){

            long begin = System.currentTimeMillis();

            for(int i=0;i<ttime;i++){

                String s = "abadf" + "abadf" + "abadf" ;

            }

            long over = System.currentTimeMillis();

            System.out.println(" 操作字符串相加使用的時間為: "

                + (over - begin) + " 毫秒 " );       

        }

       

        public static void main(String[] args){

        String s1 ="abc";

        StringBuffer sb1 = new StringBuffer("abc");

        StringBuilder sb2 = new StringBuilder("abc");

        testssb t = new testssb();

        t.test(s1);

        t.test(sb1);

        t.test(sb2);

        t.test2();

        t.test3();

        }

    }

    以上代碼在 NetBeans 5.0 IDE/JDK1.6 上編譯通過

    循環次數 ttime 10000 次的測試結果如下:

    操作 java.lang.String 類型使用的時間為: 4392 毫秒

    操作 java.lang.StringBuffer 類型使用的時間為: 0 毫秒

    操作 java.lang.StringBuilder 類型使用的時間為: 0 毫秒

    操作字符串對象引用相加類型使用的時間為: 15 毫秒

    操作字符串相加使用的時間為: 0 毫秒

    好像還看不出 StringBuffer StringBuilder 的區別,把 ttime 加到 30000 次看看:

    操作 java.lang.String 類型使用的時間為: 53444 毫秒

    操作 java.lang.StringBuffer 類型使用的時間為: 15 毫秒

    操作 java.lang.StringBuilder 類型使用的時間為: 15 毫秒

    操作字符串對象引用相加類型使用的時間為: 31 毫秒

    操作字符串相加使用的時間為: 0 毫秒

    StringBuffer StringBuilder 的性能上還是沒有太大的差異,再加大到 100000 看看,這里就不加入對 String 類型的測試了,因為對 String 類型這么大數據量的測試會很慢滴……

    操作 java.lang.StringBuffer 類型使用的時間為: 31 毫秒

    操作 java.lang.StringBuilder 類型使用的時間為: 16 毫秒

    能看出差別了,但其中有多次的測試結果居然是 StringBuffer StringBuilder 快,再加大一些到 1000000 看看(應該不會當機吧?):

    操作 java.lang.StringBuffer 類型使用的時間為: 265 毫秒

    操作 java.lang.StringBuilder 類型使用的時間為: 219 毫秒

    有些少區別了,而且結果很穩定,再大點看看, ttime = 5000000

    ······ Exception in thread "main" java.lang.OutOfMemoryError: Java heap space ······

    呵呵,算了,不去測試了,基本來說都是在性能上都是 StringBuilder > StringBuffer > String 的了。

    其實我這里測試并不是很公平,因為都放在了一起以先后順序進行,測試方法中間沒有考慮到JVM的GC收集前面產生的無引用對象垃圾而對執行過程的中斷時間。如果大家有更好的想法或者思路歡迎跟我討論:chenpengyi#gmail.com。

    posted on 2006-05-20 18:34 liaojiyong 閱讀(952) 評論(1)  編輯  收藏 所屬分類: Java

    評論

    # re: String,StringBuffer,StringBuilder(轉載) 2006-05-20 19:52 liaojiyong

    經典


      回復  更多評論   

    主站蜘蛛池模板: 日韩电影免费在线观看视频| 国产92成人精品视频免费| 性一交一乱一视频免费看| 亚洲综合精品成人| 午夜免费福利在线| 国产精品亚洲二区在线| 国产真人无遮挡作爱免费视频| 亚洲精品永久在线观看| 国产美女精品久久久久久久免费| 国产AV无码专区亚洲AV蜜芽 | 少妇性饥渴无码A区免费| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 久久久久国产精品免费免费搜索| 亚洲AV成人无码天堂| 处破痛哭A√18成年片免费| 久久亚洲精品高潮综合色a片| 免费国内精品久久久久影院| 人成电影网在线观看免费| 亚洲中文字幕无码永久在线| 日韩av无码久久精品免费| 亚洲成人福利网站| 国产免费人视频在线观看免费 | 亚洲欧美乱色情图片| 免费无遮挡无码永久在线观看视频| 麻豆va在线精品免费播放| 国产黄色一级毛片亚洲黄片大全| a毛看片免费观看视频| 亚洲综合久久成人69| 日本一道在线日本一道高清不卡免费| 杨幂最新免费特级毛片| 亚洲av日韩av天堂影片精品| 久久不见久久见免费影院| 高清免费久久午夜精品| 亚洲视频国产精品| 在线免费观看国产视频| 免费看无码特级毛片| 亚洲综合色7777情网站777| 亚洲国产中文v高清在线观看| 91久久青青草原线免费| 青青青亚洲精品国产| 亚洲福利在线观看|