实例6 - StringBuilder和StringBuffer

2018-12-28  本文已影响0人  静筱
字符操作是Java代码中最高频的操作,因此字符操作的效率极大地影响程序本身的效率。

Java中字符操作可使用StringBuilder(线程不安全),StringBuffer(线程安全)以及String.

其中String值不可变,因此在字符操作比如字符串拼接,截取等等,底层JVM处理时,实际上都会创建一个新的String对象,消耗额外资源。

因此在高频字符操作时,我们一般改为StringBuffer或者 StringBuilder进行操作,而处理完的结果再通过String返回。(详见<a href="">asdoifjew</a>)

StringBuilder和StringBuffer转成String有两种方式:

  1. new String(StringBuilder sbd) 或 new String(StringBuffer sbr)

  2. StringBuilder和StringBuffer本身的toString()方法

这两种方法的效率又如何呢?哪种效率更高呢?
下面我们通过一个实例来测试一下:

public class StringOperationTest {


    private StringBuilder getStringBuilder(){

        StringBuilder sbr = new StringBuilder();
            for(int i=0;i<10000; i++){
                sbr.append("Test");
            }
           return sbr;
    }

    private StringBuffer getStringBuffer(){
        StringBuffer sbr = new StringBuffer();
        for(int i=0;i<10000; i++){
            sbr.append("Test");
        }
        return sbr;

    }


    public static void main(String[] args){

        int k=1000;
        long max1 = 0;
        long max2 = 0;
        long max3 = 0;
        long max4 = 0;

        long min1 = 0;
        long min2 = 0;
        long min3 = 0;
        long min4 = 0;

        long sum1 = 0;
        long sum2 = 0;
        long sum3 = 0;
        long sum4 = 0;

        for(int j=0 ; j<=k; j++) {
            StringOperationTest soTest = new StringOperationTest();

            long start = System.currentTimeMillis();

            String test1 = soTest.getStringBuffer().toString();
            

            long start2 = System.currentTimeMillis();

            String test2 = soTest.getStringBuilder().toString();


            long start3 = System.currentTimeMillis();

            String test3 = new String(soTest.getStringBuffer());

            long start4 = System.currentTimeMillis();

            String test4 = new String(soTest.getStringBuilder());
            
            long time1=System.currentTimeMillis()-start;
            long time2=System.currentTimeMillis()-start2;
            long time3=System.currentTimeMillis()-start3;
            long time4=System.currentTimeMillis()-start4;
            

            if(time1>max1){
                max1 = time1;
            }

            if(time2>max2){
                max2 = time2;
            }

            if(time3>max3){
                max3 = time3;
            }

            if(time4>max4){
                max4 = time4;
            }


            if(time1<max1){
                min1 = time1;
            }

            if(time2<max2){
                min2 = time2;
            }

            if(time3<max3){
                min3 = time3;
            }

            if(time4<max4){
                min4 = time4;
            }

            sum1+=time1;
            sum2+=time2;
            sum3+=time3;
            sum4+=time4;

        }


        long avg1 = (long)sum1/k;
        long avg2 = (long)sum2/k;
        long avg3 = (long)sum3/k;
        long avg4 = (long)sum4/k;

        System.out.println("StringBuffer.toString:[max]"+max1+"ms, [min]"+min1+"ms, [avg]"+avg1+"ms");
        System.out.println("StringBuilder.toString:[max]"+max2+"ms, [min]"+min2+"ms, [avg]"+avg2+"ms");
        System.out.println("new String(StringBuffer):[max]"+max3+"ms, [min]"+min3+"ms, [avg]"+avg3+"ms");
        System.out.println("new String(StringBuilder):[max]"+max4+"ms, [min]"+min4+"ms, [avg]"+avg4+"ms");
    }
    
}

结果

StringBuffer.toString:[max]18ms, [min]2ms, [avg]1ms
StringBuilder.toString:[max]17ms, [min]2ms, [avg]1ms
new String(StringBuffer):[max]11ms, [min]1ms, [avg]0ms
new String(StringBuilder):[max]10ms, [min]0ms, [avg]0ms

从平均耗时来看StringBuffer.toString 和StringBuilder.toString一样,比String构造函数略慢。

从最大耗时来看,
StringBuffer.toString 耗时最多,其次是StringBuilder.toString, new String(StringBuffer), 最好的是new String(StringBuilder)

其中

//String类:
  public String(StringBuffer var1) {
        String var2 = var1.toString();//此处调用的是StringBuffer和toString()方法,是线程安全的
        this.value = var2.value;
        this.count = var2.count;
        this.offset = var2.offset;
    }

//StringBuffer类:
     public synchronized String toString() {
        return new String(this.value, 0, this.count);
    }   

综合来说

多线程开发,用StringBuffer,转成String时,用new String(StringBuffer sbr);

StringBuilder转成String时,用new String(StringBuilder sbe)

上一篇下一篇

猜你喜欢

热点阅读